Rename the equipment domain to machines; retype the models catalog (ADR-011)
The equipment plugin is now the machines plugin, ending the UI-vs-code vocabulary split while the contract is pre-1.0 and nothing external depends on the old names. - plugins/equipment -> plugins/machines: manifest, class, /api/machines, machines.* permissions, registry key (with an auto-migrating load shim for existing installs). - Tables: equipment -> machines (equipmentid -> machineid) and equipmenttypes -> machinetypes, renamed in the plugin's own migration chain (machines0002rename), idempotent for both upgrading and fresh installs. - The legacy core machinetypes lookup actually types the vendor MODELS catalog, so it is renamed losslessly to modeltypes (models.modeltypeid, /api/modeltypes, Model Types settings page) rather than collapsed, freeing the machinetypes name. Core migration 7d17_machines_rename also flips data in place: assettypes row equipment -> machine, auditlog entitytype, identifier_/search_ settings keys, permission rows, and renames alembic_version_equipment. - Frontend: machinesApi/modeltypesApi, item.machine response shape, assettype value compares 'equipment' -> 'machine' (map, search, custom fields, relationships), routes machines.js with plugin gating retagged, /print/machine-badge, Machine Types (subtypes) and Model Types (catalog) settings pages, machines-by-type report id. - Docs swept; ADRs left as history per the authoring rule. Upgrade: flask db upgrade then flask plugin upgrade-all. Verified: dev DB flipped live (262 machines, 35 modeltypes, 95 models retyped, zero equipment tables remain); fresh scratch-MySQL install produces the new names; 341 tests green; naming/style green; frontend builds; live E2E on machines list/detail, PC relationships, map, reports, and both settings pages. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
<div class="card">
|
||||
<div v-if="loading" class="loading">Loading...</div>
|
||||
|
||||
<form v-else @submit.prevent="saveEquipment">
|
||||
<form v-else @submit.prevent="saveMachine">
|
||||
<!-- Identity Section -->
|
||||
<h3 class="form-section-title">Identity</h3>
|
||||
<div class="form-row">
|
||||
@@ -34,8 +34,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row" v-if="isEnabled('gaugelabreference', 'equipment') || isEnabled('maintenancereference', 'equipment')">
|
||||
<div class="form-group" v-if="isEnabled('gaugelabreference', 'equipment')">
|
||||
<div class="form-row" v-if="isEnabled('gaugelabreference', 'machine') || isEnabled('maintenancereference', 'machine')">
|
||||
<div class="form-group" v-if="isEnabled('gaugelabreference', 'machine')">
|
||||
<label for="gaugelabreference">Gauge Lab Reference</label>
|
||||
<input
|
||||
id="gaugelabreference"
|
||||
@@ -46,7 +46,7 @@
|
||||
<small class="form-help">Authoritative gauge lab asset reference (if tracked)</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group" v-if="isEnabled('maintenancereference', 'equipment')">
|
||||
<div class="form-group" v-if="isEnabled('maintenancereference', 'machine')">
|
||||
<label for="maintenancereference">Maintenance Reference</label>
|
||||
<input
|
||||
id="maintenancereference"
|
||||
@@ -88,23 +88,23 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Equipment Hardware Section -->
|
||||
<!-- Machine Hardware Section -->
|
||||
<h3 class="form-section-title">Machine Hardware</h3>
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="equipmenttypeid">Equipment Type</label>
|
||||
<label for="machinetypeid">Machine Type</label>
|
||||
<select
|
||||
id="equipmenttypeid"
|
||||
v-model="form.equipmenttypeid"
|
||||
id="machinetypeid"
|
||||
v-model="form.machinetypeid"
|
||||
class="form-control"
|
||||
>
|
||||
<option value="">Select type...</option>
|
||||
<option
|
||||
v-for="et in equipmentTypes"
|
||||
:key="et.equipmenttypeid"
|
||||
:value="et.equipmenttypeid"
|
||||
v-for="mt in machineTypes"
|
||||
:key="mt.machinetypeid"
|
||||
:value="mt.machinetypeid"
|
||||
>
|
||||
{{ et.equipmenttype }}
|
||||
{{ mt.machinetype }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
@@ -294,7 +294,7 @@
|
||||
{{ pc.assetnumber }}{{ pc.name ? ` (${pc.name})` : '' }}
|
||||
</option>
|
||||
</select>
|
||||
<small class="form-help">Select the PC that controls this equipment</small>
|
||||
<small class="form-help">Select the PC that controls this machine</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group" v-if="controllingPcId">
|
||||
@@ -312,7 +312,7 @@
|
||||
{{ rt.relationshiptype }}
|
||||
</option>
|
||||
</select>
|
||||
<small class="form-help">How the PC connects to this equipment</small>
|
||||
<small class="form-help">How the PC connects to this machine</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -328,8 +328,8 @@
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
<!-- Site-defined custom fields for equipment -->
|
||||
<CustomFieldsInputs ref="customFieldsRef" :assettypeid="EQUIPMENT_ASSETTYPEID" :assetid="currentAssetId" />
|
||||
<!-- Site-defined custom fields for machines -->
|
||||
<CustomFieldsInputs ref="customFieldsRef" :assettypeid="MACHINE_ASSETTYPEID" :assetid="currentAssetId" />
|
||||
|
||||
<div v-if="error" class="error-message">{{ error }}</div>
|
||||
|
||||
@@ -347,7 +347,7 @@
|
||||
<script setup>
|
||||
import { ref, onMounted, computed, watch } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { equipmentApi, vendorsApi, locationsApi, modelsApi, businessunitsApi, computersApi, assetsApi } from '../../api'
|
||||
import { machinesApi, vendorsApi, locationsApi, modelsApi, businessunitsApi, computersApi, assetsApi } from '../../api'
|
||||
import ShopFloorMap from '../../components/ShopFloorMap.vue'
|
||||
import Modal from '../../components/Modal.vue'
|
||||
import CustomFieldsInputs from '../../components/CustomFieldsInputs.vue'
|
||||
@@ -362,8 +362,8 @@ const router = useRouter()
|
||||
|
||||
const isEdit = computed(() => !!route.params.id)
|
||||
|
||||
// Seeded asset-type id for equipment (see /api/assets/types).
|
||||
const EQUIPMENT_ASSETTYPEID = 1
|
||||
// Seeded asset-type id for machines (see /api/assets/types).
|
||||
const MACHINE_ASSETTYPEID = 1
|
||||
const customFieldsRef = ref(null)
|
||||
const currentAssetId = ref(null)
|
||||
|
||||
@@ -380,7 +380,7 @@ const form = ref({
|
||||
maintenancereference: '',
|
||||
serialnumber: '',
|
||||
statusid: 1,
|
||||
equipmenttypeid: '',
|
||||
machinetypeid: '',
|
||||
vendorid: '',
|
||||
modelnumberid: '',
|
||||
controllervendorid: '',
|
||||
@@ -394,7 +394,7 @@ const form = ref({
|
||||
mapy: null
|
||||
})
|
||||
|
||||
const equipmentTypes = ref([])
|
||||
const machineTypes = ref([])
|
||||
const statuses = ref([])
|
||||
const vendors = ref([])
|
||||
const locations = ref([])
|
||||
@@ -405,9 +405,9 @@ const relationshipTypes = ref([])
|
||||
const controllingPcId = ref(null)
|
||||
const relationshipTypeId = ref(null)
|
||||
const existingRelationshipId = ref(null)
|
||||
const currentEquipment = ref(null)
|
||||
const currentMachine = ref(null)
|
||||
|
||||
// Filter models by selected equipment vendor
|
||||
// Filter models by selected machine vendor
|
||||
const filteredModels = computed(() => {
|
||||
if (!form.value.vendorid) return models.value
|
||||
return models.value.filter(m => m.vendorid === form.value.vendorid)
|
||||
@@ -443,7 +443,7 @@ onMounted(async () => {
|
||||
try {
|
||||
// Load reference data in parallel
|
||||
const [typesRes, statusRes, vendorRes, locRes, allModels, buRes, pcsRes, relTypesRes] = await Promise.all([
|
||||
equipmentApi.types.list(),
|
||||
machinesApi.types.list(),
|
||||
assetsApi.statuses.list(),
|
||||
vendorsApi.list({ perpage: 500 }),
|
||||
locationsApi.list({ perpage: 500 }),
|
||||
@@ -453,7 +453,7 @@ onMounted(async () => {
|
||||
assetsApi.types.list() // Used for relationship types, will fix below
|
||||
])
|
||||
|
||||
equipmentTypes.value = typesRes.data.data || []
|
||||
machineTypes.value = typesRes.data.data || []
|
||||
statuses.value = statusRes.data.data || []
|
||||
vendors.value = vendorRes.data.data || []
|
||||
locations.value = locRes.data.data || []
|
||||
@@ -479,12 +479,12 @@ onMounted(async () => {
|
||||
relationshipTypeId.value = controlsType.relationshiptypeid
|
||||
}
|
||||
|
||||
// Load equipment if editing
|
||||
// Load machine if editing
|
||||
if (isEdit.value) {
|
||||
const response = await equipmentApi.get(route.params.id)
|
||||
const response = await machinesApi.get(route.params.id)
|
||||
const data = response.data.data
|
||||
currentAssetId.value = data.assetid || null
|
||||
currentEquipment.value = data
|
||||
currentMachine.value = data
|
||||
|
||||
form.value = {
|
||||
assetnumber: data.assetnumber || '',
|
||||
@@ -493,15 +493,15 @@ onMounted(async () => {
|
||||
maintenancereference: data.maintenancereference || '',
|
||||
serialnumber: data.serialnumber || '',
|
||||
statusid: data.statusid || 1,
|
||||
equipmenttypeid: data.equipment?.equipmenttypeid || '',
|
||||
vendorid: data.equipment?.vendorid || '',
|
||||
modelnumberid: data.equipment?.modelnumberid || '',
|
||||
controllervendorid: data.equipment?.controllervendorid || '',
|
||||
controllermodelid: data.equipment?.controllermodelid || '',
|
||||
machinetypeid: data.machine?.machinetypeid || '',
|
||||
vendorid: data.machine?.vendorid || '',
|
||||
modelnumberid: data.machine?.modelnumberid || '',
|
||||
controllervendorid: data.machine?.controllervendorid || '',
|
||||
controllermodelid: data.machine?.controllermodelid || '',
|
||||
locationid: data.locationid || '',
|
||||
businessunitid: data.businessunitid || '',
|
||||
requiresmanualconfig: data.equipment?.requiresmanualconfig || false,
|
||||
islocationonly: data.equipment?.islocationonly || false,
|
||||
requiresmanualconfig: data.machine?.requiresmanualconfig || false,
|
||||
islocationonly: data.machine?.islocationonly || false,
|
||||
notes: data.notes || '',
|
||||
mapx: data.mapx ?? null,
|
||||
mapy: data.mapy ?? null
|
||||
@@ -553,7 +553,7 @@ function clearMapPosition() {
|
||||
tempMapPosition.value = null
|
||||
}
|
||||
|
||||
async function saveEquipment() {
|
||||
async function saveMachine() {
|
||||
error.value = ''
|
||||
saving.value = true
|
||||
|
||||
@@ -565,7 +565,7 @@ async function saveEquipment() {
|
||||
maintenancereference: form.value.maintenancereference || null,
|
||||
serialnumber: form.value.serialnumber || null,
|
||||
statusid: form.value.statusid || 1,
|
||||
equipmenttypeid: form.value.equipmenttypeid || null,
|
||||
machinetypeid: form.value.machinetypeid || null,
|
||||
vendorid: form.value.vendorid || null,
|
||||
modelnumberid: form.value.modelnumberid || null,
|
||||
controllervendorid: form.value.controllervendorid || null,
|
||||
@@ -579,17 +579,17 @@ async function saveEquipment() {
|
||||
mapy: form.value.mapy
|
||||
}
|
||||
|
||||
let savedEquipment
|
||||
let savedMachine
|
||||
let assetId
|
||||
|
||||
if (isEdit.value) {
|
||||
const response = await equipmentApi.update(route.params.id, data)
|
||||
savedEquipment = response.data.data
|
||||
assetId = savedEquipment.assetid
|
||||
const response = await machinesApi.update(route.params.id, data)
|
||||
savedMachine = response.data.data
|
||||
assetId = savedMachine.assetid
|
||||
} else {
|
||||
const response = await equipmentApi.create(data)
|
||||
savedEquipment = response.data.data
|
||||
assetId = savedEquipment.assetid
|
||||
const response = await machinesApi.create(data)
|
||||
savedMachine = response.data.data
|
||||
assetId = savedMachine.assetid
|
||||
}
|
||||
|
||||
// Handle relationship (controlling PC)
|
||||
@@ -604,10 +604,10 @@ async function saveEquipment() {
|
||||
}
|
||||
}
|
||||
|
||||
router.push(`/machines/${savedEquipment.equipment?.equipmentid || route.params.id}`)
|
||||
router.push(`/machines/${savedMachine.machine?.machineid || route.params.id}`)
|
||||
} catch (err) {
|
||||
console.error('Error saving equipment:', err)
|
||||
error.value = apiError(err, 'Failed to save equipment')
|
||||
console.error('Error saving machine:', err)
|
||||
error.value = apiError(err, 'Failed to save machine')
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
@@ -632,7 +632,7 @@ async function saveRelationship(assetId) {
|
||||
await assetsApi.deleteRelationship(existingRelationshipId.value)
|
||||
}
|
||||
|
||||
// Create new relationship (PC controls Equipment, so PC is source, Equipment is target)
|
||||
// Create new relationship (PC controls Machine, so PC is source, Machine is target)
|
||||
await assetsApi.createRelationship({
|
||||
sourceassetid: controllingPcId.value,
|
||||
targetassetid: assetId,
|
||||
|
||||
Reference in New Issue
Block a user