591 lines
17 KiB
TypeScript
591 lines
17 KiB
TypeScript
import type {
|
|
ClientAccessAccount,
|
|
ClientAccessPowerBiExport,
|
|
MixCalculatorOptions,
|
|
MixCalculatorSession,
|
|
Mix,
|
|
Product,
|
|
ProductCostBreakdown,
|
|
RawMaterial,
|
|
Scenario
|
|
} from '$lib/types';
|
|
|
|
const MODULE_PERMISSIONS = {
|
|
superadmin: {
|
|
dashboard: 'edit',
|
|
raw_materials: 'edit',
|
|
mix_master: 'edit',
|
|
mix_calculator: 'manage',
|
|
products: 'edit',
|
|
scenarios: 'edit',
|
|
powerbi_export: 'edit',
|
|
client_access: 'manage'
|
|
},
|
|
operator: {
|
|
dashboard: 'edit',
|
|
raw_materials: 'edit',
|
|
mix_master: 'edit',
|
|
mix_calculator: 'edit',
|
|
products: 'edit',
|
|
scenarios: 'edit',
|
|
powerbi_export: 'none',
|
|
client_access: 'none'
|
|
},
|
|
viewer: {
|
|
dashboard: 'view',
|
|
raw_materials: 'none',
|
|
mix_master: 'none',
|
|
mix_calculator: 'view',
|
|
products: 'view',
|
|
scenarios: 'none',
|
|
powerbi_export: 'view',
|
|
client_access: 'none'
|
|
}
|
|
} as const;
|
|
|
|
const MODULE_DETAILS = [
|
|
['dashboard', 'Dashboard', 'workspace', 'Top-level operational dashboard'],
|
|
['raw_materials', 'Raw Materials', 'costing', 'Maintain live material costs and versions'],
|
|
['mix_master', 'Mix Master', 'costing', 'Create and maintain mix worksheets'],
|
|
['mix_calculator', 'Mix Calculator', 'production', 'Create and review client-specific mix calculation sessions'],
|
|
['products', 'Products', 'pricing', 'Review finished product pricing'],
|
|
['scenarios', 'Scenarios', 'planning', 'Run scenario overrides and comparisons'],
|
|
['powerbi_export', 'Power BI Export', 'reporting', 'Expose client access data to BI consumers'],
|
|
['client_access', 'Client Access', 'administration', 'Manage user access, module permissions, and audit history']
|
|
] as const;
|
|
|
|
export const mockRawMaterials: RawMaterial[] = [
|
|
{
|
|
id: 1,
|
|
name: 'Maize',
|
|
unit_of_measure: 'tonne',
|
|
kg_per_unit: 1000,
|
|
status: 'active',
|
|
current_price: {
|
|
market_value: 520,
|
|
waste_percentage: 0.02,
|
|
cost_per_kg: 0.5304,
|
|
effective_date: '2026-04-01'
|
|
}
|
|
},
|
|
{
|
|
id: 2,
|
|
name: 'Barley',
|
|
unit_of_measure: 'tonne',
|
|
kg_per_unit: 1000,
|
|
status: 'active',
|
|
current_price: {
|
|
market_value: 470,
|
|
waste_percentage: 0.015,
|
|
cost_per_kg: 0.4771,
|
|
effective_date: '2026-04-01'
|
|
}
|
|
}
|
|
];
|
|
|
|
export const mockMixes: Mix[] = [
|
|
{
|
|
id: 1,
|
|
client_name: 'Hunter Premium Produce',
|
|
name: 'Hunter Orchard Blend',
|
|
status: 'active',
|
|
ingredients: [
|
|
{
|
|
id: 1,
|
|
raw_material_id: 1,
|
|
raw_material_name: 'Maize',
|
|
quantity_kg: 180,
|
|
cost_per_kg: 0.5304,
|
|
line_cost: 95.472
|
|
},
|
|
{
|
|
id: 2,
|
|
raw_material_id: 2,
|
|
raw_material_name: 'Barley',
|
|
quantity_kg: 100,
|
|
cost_per_kg: 0.4771,
|
|
line_cost: 47.71
|
|
}
|
|
],
|
|
total_mix_kg: 280,
|
|
total_mix_cost: 143.18,
|
|
mix_cost_per_kg: 0.5114,
|
|
warnings: []
|
|
}
|
|
];
|
|
|
|
export const mockProducts: Product[] = [
|
|
{
|
|
id: 1,
|
|
name: 'Hunter Orchard Blend 20kg',
|
|
client_name: 'Hunter Premium Produce',
|
|
mix_id: 1,
|
|
mix_name: 'Hunter Orchard Blend',
|
|
sale_type: 'standard',
|
|
unit_of_measure: '20kg bag',
|
|
distributor_margin: 0.225,
|
|
wholesale_margin: 0.18
|
|
}
|
|
];
|
|
|
|
export const mockMixCalculatorOptions: MixCalculatorOptions = {
|
|
clients: ['Hunter Premium Produce'],
|
|
products: [
|
|
{
|
|
product_id: 1,
|
|
client_name: 'Hunter Premium Produce',
|
|
product_name: 'Hunter Orchard Blend 20kg',
|
|
mix_id: 1,
|
|
mix_name: 'Hunter Orchard Blend',
|
|
unit_of_measure: '20kg bag',
|
|
unit_size_kg: 20,
|
|
mix_total_kg: 280
|
|
}
|
|
]
|
|
};
|
|
|
|
export const mockMixCalculatorSessions: MixCalculatorSession[] = [
|
|
{
|
|
id: 1,
|
|
tenant_id: 'hunter-premium-produce',
|
|
session_number: 'HPP-20260429-0001',
|
|
client_name: 'Hunter Premium Produce',
|
|
product_id: 1,
|
|
product_name: 'Hunter Orchard Blend 20kg',
|
|
mix_id: 1,
|
|
mix_name: 'Hunter Orchard Blend',
|
|
mix_date: '2026-04-29',
|
|
batch_size_kg: 560,
|
|
total_bags: 28,
|
|
total_kg: 560,
|
|
product_unit_of_measure: '20kg bag',
|
|
product_unit_size_kg: 20,
|
|
prepared_by_user_id: 1,
|
|
prepared_by_name: 'Amelia Hart',
|
|
created_by: 'operator@example.com',
|
|
status: 'saved',
|
|
notes: 'Morning production run',
|
|
created_at: '2026-04-29T08:10:00',
|
|
updated_at: '2026-04-29T08:12:00',
|
|
warnings: [],
|
|
is_owner: true,
|
|
lines: [
|
|
{
|
|
id: 1,
|
|
raw_material_id: 1,
|
|
raw_material_name: 'Maize',
|
|
required_kg: 360,
|
|
mix_percentage: 64.2857,
|
|
unit: 'tonne',
|
|
sort_order: 1
|
|
},
|
|
{
|
|
id: 2,
|
|
raw_material_id: 2,
|
|
raw_material_name: 'Barley',
|
|
required_kg: 200,
|
|
mix_percentage: 35.7143,
|
|
unit: 'tonne',
|
|
sort_order: 2
|
|
}
|
|
]
|
|
}
|
|
];
|
|
|
|
export const mockCosts: ProductCostBreakdown[] = [
|
|
{
|
|
product_id: 1,
|
|
product_name: 'Hunter Orchard Blend 20kg',
|
|
client_name: 'Hunter Premium Produce',
|
|
mix_name: 'Hunter Orchard Blend',
|
|
finished_product_delivered: 14.208,
|
|
distributor_price: 18.3329,
|
|
wholesale_price: 17.3268,
|
|
warnings: []
|
|
}
|
|
];
|
|
|
|
export const mockScenarios: Scenario[] = [
|
|
{
|
|
id: 1,
|
|
name: 'Current Standard',
|
|
status: 'approved',
|
|
description: 'Baseline approved pricing',
|
|
overrides: {}
|
|
}
|
|
];
|
|
|
|
export const mockClientAccess: ClientAccessAccount[] = [
|
|
{
|
|
id: 1,
|
|
tenant_id: 'hunter-premium-produce',
|
|
name: 'Hunter Premium Produce',
|
|
client_code: 'HPP',
|
|
status: 'active',
|
|
powerbi_workspace: 'hunter-premium-produce-prod',
|
|
notes: 'Primary production client for the Lean 101 admin and access workflows',
|
|
created_at: '2026-04-20T09:00:00',
|
|
active_user_count: 1,
|
|
new_user_count: 1,
|
|
enabled_feature_count: 8,
|
|
total_feature_count: 8,
|
|
users: [
|
|
{
|
|
id: 1,
|
|
client_account_id: 1,
|
|
full_name: 'Amelia Hart',
|
|
email: 'operator@example.com',
|
|
role: 'superadmin',
|
|
status: 'active',
|
|
is_new_user: false,
|
|
last_login_at: '2026-04-24T11:30:00',
|
|
created_at: '2026-04-20T09:00:00',
|
|
module_permissions: MODULE_DETAILS.map(([module_key, module_name, module_group, description], index) => ({
|
|
id: index + 1,
|
|
client_account_id: 1,
|
|
client_user_id: 1,
|
|
module_key,
|
|
module_name,
|
|
module_group,
|
|
description,
|
|
access_level: MODULE_PERMISSIONS.superadmin[module_key],
|
|
updated_at: '2026-04-24T15:00:00',
|
|
created_at: '2026-04-20T09:00:00'
|
|
}))
|
|
},
|
|
{
|
|
id: 2,
|
|
client_account_id: 1,
|
|
full_name: 'Ethan Cole',
|
|
email: 'ethan.cole@hunterpremiumproduce.example',
|
|
role: 'operator',
|
|
status: 'invited',
|
|
is_new_user: true,
|
|
last_login_at: null,
|
|
created_at: '2026-04-24T15:00:00',
|
|
module_permissions: MODULE_DETAILS.map(([module_key, module_name, module_group, description], index) => ({
|
|
id: index + 101,
|
|
client_account_id: 1,
|
|
client_user_id: 2,
|
|
module_key,
|
|
module_name,
|
|
module_group,
|
|
description,
|
|
access_level: MODULE_PERMISSIONS.operator[module_key],
|
|
updated_at: '2026-04-24T15:00:00',
|
|
created_at: '2026-04-24T15:00:00'
|
|
}))
|
|
}
|
|
],
|
|
features: [
|
|
{
|
|
id: 1,
|
|
client_account_id: 1,
|
|
feature_key: 'dashboard',
|
|
feature_name: 'Dashboard',
|
|
feature_group: 'workspace',
|
|
description: 'Top-level operational dashboard',
|
|
enabled: true,
|
|
updated_at: '2026-04-24T15:00:00',
|
|
created_at: '2026-04-20T09:00:00'
|
|
},
|
|
{
|
|
id: 2,
|
|
client_account_id: 1,
|
|
feature_key: 'raw_materials',
|
|
feature_name: 'Raw Materials',
|
|
feature_group: 'costing',
|
|
description: 'Maintain live material costs and versions',
|
|
enabled: true,
|
|
updated_at: '2026-04-24T15:00:00',
|
|
created_at: '2026-04-20T09:00:00'
|
|
},
|
|
{
|
|
id: 3,
|
|
client_account_id: 1,
|
|
feature_key: 'mix_master',
|
|
feature_name: 'Mix Master',
|
|
feature_group: 'costing',
|
|
description: 'Create and maintain mix worksheets',
|
|
enabled: true,
|
|
updated_at: '2026-04-24T15:00:00',
|
|
created_at: '2026-04-20T09:00:00'
|
|
},
|
|
{
|
|
id: 4,
|
|
client_account_id: 1,
|
|
feature_key: 'mix_calculator',
|
|
feature_name: 'Mix Calculator',
|
|
feature_group: 'production',
|
|
description: 'Create and review client-specific mix calculation sessions',
|
|
enabled: true,
|
|
updated_at: '2026-04-24T15:00:00',
|
|
created_at: '2026-04-20T09:00:00'
|
|
},
|
|
{
|
|
id: 5,
|
|
client_account_id: 1,
|
|
feature_key: 'products',
|
|
feature_name: 'Products',
|
|
feature_group: 'pricing',
|
|
description: 'Review finished product pricing',
|
|
enabled: true,
|
|
updated_at: '2026-04-24T15:00:00',
|
|
created_at: '2026-04-20T09:00:00'
|
|
},
|
|
{
|
|
id: 6,
|
|
client_account_id: 1,
|
|
feature_key: 'scenarios',
|
|
feature_name: 'Scenarios',
|
|
feature_group: 'planning',
|
|
description: 'Run scenario overrides and comparisons',
|
|
enabled: true,
|
|
updated_at: '2026-04-24T15:00:00',
|
|
created_at: '2026-04-20T09:00:00'
|
|
},
|
|
{
|
|
id: 7,
|
|
client_account_id: 1,
|
|
feature_key: 'powerbi_export',
|
|
feature_name: 'Power BI Export',
|
|
feature_group: 'reporting',
|
|
description: 'Expose client access data to BI consumers',
|
|
enabled: true,
|
|
updated_at: '2026-04-24T15:00:00',
|
|
created_at: '2026-04-20T09:00:00'
|
|
},
|
|
{
|
|
id: 8,
|
|
client_account_id: 1,
|
|
feature_key: 'client_access',
|
|
feature_name: 'Client Access',
|
|
feature_group: 'administration',
|
|
description: 'Manage user access, module permissions, and audit history',
|
|
enabled: true,
|
|
updated_at: '2026-04-24T15:00:00',
|
|
created_at: '2026-04-20T09:00:00'
|
|
}
|
|
],
|
|
audit_history: [
|
|
{
|
|
id: 1,
|
|
client_account_id: 1,
|
|
actor_type: 'lean_admin',
|
|
actor_name: 'Lean 101 Seeder',
|
|
actor_email: 'system@lean101.local',
|
|
actor_role: 'system',
|
|
action: 'client_access.seeded',
|
|
target_type: 'client_account',
|
|
target_id: 1,
|
|
module_key: 'client_access',
|
|
summary: 'Initial client access controls, module permissions, and feature flags were seeded.',
|
|
created_at: '2026-04-20T09:00:00'
|
|
}
|
|
]
|
|
},
|
|
{
|
|
id: 2,
|
|
tenant_id: 'loft-grains',
|
|
name: 'Loft Grains',
|
|
client_code: 'LOFT',
|
|
status: 'onboarding',
|
|
powerbi_workspace: 'farm-ops-sandbox',
|
|
notes: 'Onboarding workspace used to test staged user enablement',
|
|
created_at: '2026-04-21T10:00:00',
|
|
active_user_count: 1,
|
|
new_user_count: 0,
|
|
enabled_feature_count: 4,
|
|
total_feature_count: 8,
|
|
users: [
|
|
{
|
|
id: 3,
|
|
client_account_id: 2,
|
|
full_name: 'Ruby Singh',
|
|
email: 'ruby.singh@loftgrains.example',
|
|
role: 'viewer',
|
|
status: 'active',
|
|
is_new_user: false,
|
|
last_login_at: '2026-04-22T09:10:00',
|
|
created_at: '2026-04-21T10:00:00',
|
|
module_permissions: MODULE_DETAILS.map(([module_key, module_name, module_group, description], index) => ({
|
|
id: index + 201,
|
|
client_account_id: 2,
|
|
client_user_id: 3,
|
|
module_key,
|
|
module_name,
|
|
module_group,
|
|
description,
|
|
access_level: MODULE_PERMISSIONS.viewer[module_key],
|
|
updated_at: '2026-04-22T09:10:00',
|
|
created_at: '2026-04-21T10:00:00'
|
|
}))
|
|
}
|
|
],
|
|
features: [
|
|
{
|
|
id: 7,
|
|
client_account_id: 2,
|
|
feature_key: 'dashboard',
|
|
feature_name: 'Dashboard',
|
|
feature_group: 'workspace',
|
|
description: 'Top-level operational dashboard',
|
|
enabled: true,
|
|
updated_at: '2026-04-22T09:10:00',
|
|
created_at: '2026-04-21T10:00:00'
|
|
},
|
|
{
|
|
id: 8,
|
|
client_account_id: 2,
|
|
feature_key: 'raw_materials',
|
|
feature_name: 'Raw Materials',
|
|
feature_group: 'costing',
|
|
description: 'Maintain live material costs and versions',
|
|
enabled: false,
|
|
updated_at: '2026-04-22T09:10:00',
|
|
created_at: '2026-04-21T10:00:00'
|
|
},
|
|
{
|
|
id: 9,
|
|
client_account_id: 2,
|
|
feature_key: 'mix_master',
|
|
feature_name: 'Mix Master',
|
|
feature_group: 'costing',
|
|
description: 'Create and maintain mix worksheets',
|
|
enabled: false,
|
|
updated_at: '2026-04-22T09:10:00',
|
|
created_at: '2026-04-21T10:00:00'
|
|
},
|
|
{
|
|
id: 10,
|
|
client_account_id: 2,
|
|
feature_key: 'mix_calculator',
|
|
feature_name: 'Mix Calculator',
|
|
feature_group: 'production',
|
|
description: 'Create and review client-specific mix calculation sessions',
|
|
enabled: true,
|
|
updated_at: '2026-04-22T09:10:00',
|
|
created_at: '2026-04-21T10:00:00'
|
|
},
|
|
{
|
|
id: 11,
|
|
client_account_id: 2,
|
|
feature_key: 'products',
|
|
feature_name: 'Products',
|
|
feature_group: 'pricing',
|
|
description: 'Review finished product pricing',
|
|
enabled: true,
|
|
updated_at: '2026-04-22T09:10:00',
|
|
created_at: '2026-04-21T10:00:00'
|
|
},
|
|
{
|
|
id: 12,
|
|
client_account_id: 2,
|
|
feature_key: 'scenarios',
|
|
feature_name: 'Scenarios',
|
|
feature_group: 'planning',
|
|
description: 'Run scenario overrides and comparisons',
|
|
enabled: false,
|
|
updated_at: '2026-04-22T09:10:00',
|
|
created_at: '2026-04-21T10:00:00'
|
|
},
|
|
{
|
|
id: 13,
|
|
client_account_id: 2,
|
|
feature_key: 'powerbi_export',
|
|
feature_name: 'Power BI Export',
|
|
feature_group: 'reporting',
|
|
description: 'Expose client access data to BI consumers',
|
|
enabled: true,
|
|
updated_at: '2026-04-22T09:10:00',
|
|
created_at: '2026-04-21T10:00:00'
|
|
},
|
|
{
|
|
id: 14,
|
|
client_account_id: 2,
|
|
feature_key: 'client_access',
|
|
feature_name: 'Client Access',
|
|
feature_group: 'administration',
|
|
description: 'Manage user access, module permissions, and audit history',
|
|
enabled: false,
|
|
updated_at: '2026-04-22T09:10:00',
|
|
created_at: '2026-04-21T10:00:00'
|
|
}
|
|
],
|
|
audit_history: []
|
|
}
|
|
];
|
|
|
|
export const mockClientAccessExport: ClientAccessPowerBiExport = {
|
|
generated_at: '2026-04-25T09:00:00',
|
|
client_rows: mockClientAccess.map((client) => ({
|
|
client_id: client.id,
|
|
tenant_id: client.tenant_id,
|
|
client_name: client.name,
|
|
client_code: client.client_code,
|
|
client_status: client.status,
|
|
powerbi_workspace: client.powerbi_workspace,
|
|
active_user_count: client.active_user_count,
|
|
new_user_count: client.new_user_count,
|
|
enabled_feature_count: client.enabled_feature_count,
|
|
total_feature_count: client.total_feature_count
|
|
})),
|
|
user_rows: mockClientAccess.flatMap((client) =>
|
|
client.users.map((user) => ({
|
|
client_id: client.id,
|
|
client_name: client.name,
|
|
user_id: user.id,
|
|
full_name: user.full_name,
|
|
email: user.email,
|
|
role: user.role,
|
|
status: user.status,
|
|
is_new_user: user.is_new_user,
|
|
last_login_at: user.last_login_at,
|
|
created_at: user.created_at
|
|
}))
|
|
),
|
|
feature_rows: mockClientAccess.flatMap((client) =>
|
|
client.features.map((feature) => ({
|
|
client_id: client.id,
|
|
client_name: client.name,
|
|
feature_id: feature.id,
|
|
feature_key: feature.feature_key,
|
|
feature_name: feature.feature_name,
|
|
feature_group: feature.feature_group,
|
|
enabled: feature.enabled,
|
|
updated_at: feature.updated_at
|
|
}))
|
|
),
|
|
permission_rows: mockClientAccess.flatMap((client) =>
|
|
client.users.flatMap((user) =>
|
|
user.module_permissions.map((permission) => ({
|
|
client_id: client.id,
|
|
client_name: client.name,
|
|
user_id: user.id,
|
|
user_email: user.email,
|
|
module_key: permission.module_key,
|
|
module_name: permission.module_name,
|
|
module_group: permission.module_group,
|
|
access_level: permission.access_level,
|
|
updated_at: permission.updated_at
|
|
}))
|
|
)
|
|
),
|
|
audit_rows: mockClientAccess.flatMap((client) =>
|
|
client.audit_history.map((event) => ({
|
|
client_id: client.id,
|
|
client_name: client.name,
|
|
event_id: event.id,
|
|
actor_email: event.actor_email,
|
|
actor_role: event.actor_role,
|
|
action: event.action,
|
|
target_type: event.target_type,
|
|
target_id: event.target_id,
|
|
module_key: event.module_key,
|
|
summary: event.summary,
|
|
created_at: event.created_at
|
|
}))
|
|
),
|
|
clients: mockClientAccess
|
|
};
|