diff --git a/docs/QUICK_REFERENCE_FIELD_LOCK.md b/docs/DEVICE_FIELD_LOCK.md
similarity index 98%
rename from docs/QUICK_REFERENCE_FIELD_LOCK.md
rename to docs/DEVICE_FIELD_LOCK.md
index fb68cc63c..2b40f80f5 100644
--- a/docs/QUICK_REFERENCE_FIELD_LOCK.md
+++ b/docs/DEVICE_FIELD_LOCK.md
@@ -1,6 +1,8 @@
# Quick Reference Guide - Device Field Lock/Unlock System
-## One-Minute Overview
+## Overview
+
+
The device field lock/unlock system allows you to protect specific device fields from being automatically overwritten by scanning plugins. When you lock a field, NetAlertX remembers your choice and prevents plugins from changing that value until you unlock it.
diff --git a/docs/DEVICE_MANAGEMENT.md b/docs/DEVICE_MANAGEMENT.md
index d1c663470..9d320bcf6 100755
--- a/docs/DEVICE_MANAGEMENT.md
+++ b/docs/DEVICE_MANAGEMENT.md
@@ -49,6 +49,8 @@ To speed up device population you can also copy data from an existing device. Th
## Field Locking (Preventing Plugin Overwrites)
+
+
NetAlertX allows you to "lock" specific device fields to prevent plugins from automatically overwriting your custom values. This is useful when you've manually corrected information that might be discovered differently by discovery plugins.
### Quick Start
@@ -64,7 +66,7 @@ The following 10 fields support locking:
### See Also
-- **For Users:** [Quick Reference - Device Field Lock/Unlock](QUICK_REFERENCE_FIELD_LOCK.md) - How to use field locking
+- **For Users:** [Quick Reference - Device Field Lock/Unlock](DEVICE_FIELD_LOCK.md) - How to use field locking
- **For Developers:** [API Device Field Lock Documentation](API_DEVICE_FIELD_LOCK.md) - Technical API reference
- **For Plugin Developers:** [Plugin Field Configuration (SET_ALWAYS/SET_EMPTY)](PLUGINS_DEV_CONFIG.md) - Configure which fields plugins can update
diff --git a/docs/img/DEVICE_MANAGEMENT/field_sources_and_locks.png b/docs/img/DEVICE_MANAGEMENT/field_sources_and_locks.png
new file mode 100644
index 000000000..4b4b4b144
Binary files /dev/null and b/docs/img/DEVICE_MANAGEMENT/field_sources_and_locks.png differ
diff --git a/front/deviceDetailsEdit.php b/front/deviceDetailsEdit.php
index 2d0d23108..1124763a6 100755
--- a/front/deviceDetailsEdit.php
+++ b/front/deviceDetailsEdit.php
@@ -440,6 +440,7 @@ function setDeviceData(direction = '', refreshCallback = '') {
devSSID: $('#NEWDEV_devSSID').val(),
devSite: $('#NEWDEV_devSite').val(),
+ devVlan: $('#NEWDEV_devVlan').val(),
devStaticIP: ($('#NEWDEV_devStaticIP')[0].checked * 1),
devScan: 1,
@@ -580,6 +581,12 @@ function toggleFieldLock(mac, fieldName) {
const currentSource = deviceData[sourceField] || "N/A";
const shouldLock = currentSource !== "LOCKED";
+ if(shouldLock && somethingChanged)
+ {
+ showMessage(getString("FieldLock_SaveBeforeLocking"), 5000, "modal_red");
+ return;
+ }
+
const payload = {
fieldName: fieldName,
lock: shouldLock ? 1 : 0
diff --git a/front/php/templates/language/ar_ar.json b/front/php/templates/language/ar_ar.json
index ab417397d..e97400ba7 100644
--- a/front/php/templates/language/ar_ar.json
+++ b/front/php/templates/language/ar_ar.json
@@ -300,6 +300,7 @@
"FieldLock_Error": "",
"FieldLock_Lock_Tooltip": "",
"FieldLock_Locked": "",
+ "FieldLock_SaveBeforeLocking": "",
"FieldLock_Source_Label": "",
"FieldLock_Unlock_Tooltip": "",
"FieldLock_Unlocked": "",
@@ -782,4 +783,4 @@
"settings_system_label": "نظام",
"settings_update_item_warning": "قم بتحديث القيمة أدناه. احرص على اتباع التنسيق السابق. لم يتم إجراء التحقق.",
"test_event_tooltip": "احفظ التغييرات أولاً قبل اختبار الإعدادات."
-}
+}
\ No newline at end of file
diff --git a/front/php/templates/language/ca_ca.json b/front/php/templates/language/ca_ca.json
index dad26da43..88de31f20 100644
--- a/front/php/templates/language/ca_ca.json
+++ b/front/php/templates/language/ca_ca.json
@@ -300,6 +300,7 @@
"FieldLock_Error": "",
"FieldLock_Lock_Tooltip": "",
"FieldLock_Locked": "",
+ "FieldLock_SaveBeforeLocking": "",
"FieldLock_Source_Label": "",
"FieldLock_Unlock_Tooltip": "",
"FieldLock_Unlocked": "",
@@ -782,4 +783,4 @@
"settings_system_label": "Sistema",
"settings_update_item_warning": "Actualitza el valor sota. Sigues curós de seguir el format anterior. No hi ha validació.",
"test_event_tooltip": "Deseu els canvis primer abans de comprovar la configuració."
-}
+}
\ No newline at end of file
diff --git a/front/php/templates/language/cs_cz.json b/front/php/templates/language/cs_cz.json
index 73c1e2d61..5bad90f8e 100644
--- a/front/php/templates/language/cs_cz.json
+++ b/front/php/templates/language/cs_cz.json
@@ -300,6 +300,7 @@
"FieldLock_Error": "",
"FieldLock_Lock_Tooltip": "",
"FieldLock_Locked": "",
+ "FieldLock_SaveBeforeLocking": "",
"FieldLock_Source_Label": "",
"FieldLock_Unlock_Tooltip": "",
"FieldLock_Unlocked": "",
diff --git a/front/php/templates/language/de_de.json b/front/php/templates/language/de_de.json
index d1a3a956d..28c3e3af3 100644
--- a/front/php/templates/language/de_de.json
+++ b/front/php/templates/language/de_de.json
@@ -304,6 +304,7 @@
"FieldLock_Error": "",
"FieldLock_Lock_Tooltip": "",
"FieldLock_Locked": "",
+ "FieldLock_SaveBeforeLocking": "",
"FieldLock_Source_Label": "",
"FieldLock_Unlock_Tooltip": "",
"FieldLock_Unlocked": "",
@@ -855,4 +856,4 @@
"settings_system_label": "System",
"settings_update_item_warning": "",
"test_event_tooltip": "Speichere die Änderungen, bevor Sie die Einstellungen testen."
-}
+}
\ No newline at end of file
diff --git a/front/php/templates/language/en_us.json b/front/php/templates/language/en_us.json
index 939e221ea..30141a601 100755
--- a/front/php/templates/language/en_us.json
+++ b/front/php/templates/language/en_us.json
@@ -300,6 +300,7 @@
"FieldLock_Error": "Error updating field lock status",
"FieldLock_Lock_Tooltip": "Lock field (prevent plugin overwrites)",
"FieldLock_Locked": "Field locked",
+ "FieldLock_SaveBeforeLocking": "Save your changes before locking",
"FieldLock_Source_Label": "Source: ",
"FieldLock_Unlock_Tooltip": "Unlock field (allow plugin overwrites)",
"FieldLock_Unlocked": "Field unlocked",
diff --git a/front/php/templates/language/es_es.json b/front/php/templates/language/es_es.json
index cfee04775..58f3627b0 100644
--- a/front/php/templates/language/es_es.json
+++ b/front/php/templates/language/es_es.json
@@ -302,6 +302,7 @@
"FieldLock_Error": "",
"FieldLock_Lock_Tooltip": "",
"FieldLock_Locked": "",
+ "FieldLock_SaveBeforeLocking": "",
"FieldLock_Source_Label": "",
"FieldLock_Unlock_Tooltip": "",
"FieldLock_Unlocked": "",
@@ -853,4 +854,4 @@
"settings_system_label": "Sistema",
"settings_update_item_warning": "Actualice el valor a continuación. Tenga cuidado de seguir el formato anterior. O la validación no se realiza.",
"test_event_tooltip": "Guarda tus cambios antes de probar nuevos ajustes."
-}
+}
\ No newline at end of file
diff --git a/front/php/templates/language/fa_fa.json b/front/php/templates/language/fa_fa.json
index d9e816698..8fe5e7bee 100644
--- a/front/php/templates/language/fa_fa.json
+++ b/front/php/templates/language/fa_fa.json
@@ -300,6 +300,7 @@
"FieldLock_Error": "",
"FieldLock_Lock_Tooltip": "",
"FieldLock_Locked": "",
+ "FieldLock_SaveBeforeLocking": "",
"FieldLock_Source_Label": "",
"FieldLock_Unlock_Tooltip": "",
"FieldLock_Unlocked": "",
diff --git a/front/php/templates/language/fr_fr.json b/front/php/templates/language/fr_fr.json
index 69bc96132..cba1e8070 100644
--- a/front/php/templates/language/fr_fr.json
+++ b/front/php/templates/language/fr_fr.json
@@ -300,6 +300,7 @@
"FieldLock_Error": "",
"FieldLock_Lock_Tooltip": "",
"FieldLock_Locked": "",
+ "FieldLock_SaveBeforeLocking": "",
"FieldLock_Source_Label": "",
"FieldLock_Unlock_Tooltip": "",
"FieldLock_Unlocked": "",
@@ -782,4 +783,4 @@
"settings_system_label": "Système",
"settings_update_item_warning": "Mettre à jour la valeur ci-dessous. Veillez à bien suivre le même format qu'auparavant. Il n'y a pas de pas de contrôle.",
"test_event_tooltip": "Enregistrer d'abord vos modifications avant de tester vôtre paramétrage."
-}
+}
\ No newline at end of file
diff --git a/front/php/templates/language/it_it.json b/front/php/templates/language/it_it.json
index a45cf7b53..55f9394fb 100644
--- a/front/php/templates/language/it_it.json
+++ b/front/php/templates/language/it_it.json
@@ -300,6 +300,7 @@
"FieldLock_Error": "Errore durante l'aggiornamento dello stato di blocco del campo",
"FieldLock_Lock_Tooltip": "Blocca campo (impedisci sovrascrittura plugin)",
"FieldLock_Locked": "Campo bloccato",
+ "FieldLock_SaveBeforeLocking": "",
"FieldLock_Source_Label": "Sorgente: ",
"FieldLock_Unlock_Tooltip": "Sblocca campo (consenti sovrascritture plugin)",
"FieldLock_Unlocked": "Campo sbloccato",
@@ -782,4 +783,4 @@
"settings_system_label": "Sistema",
"settings_update_item_warning": "Aggiorna il valore qui sotto. Fai attenzione a seguire il formato precedente. La convalida non viene eseguita.",
"test_event_tooltip": "Salva le modifiche prima di provare le nuove impostazioni."
-}
+}
\ No newline at end of file
diff --git a/front/php/templates/language/ja_jp.json b/front/php/templates/language/ja_jp.json
index 97ecb6b02..f9578a103 100644
--- a/front/php/templates/language/ja_jp.json
+++ b/front/php/templates/language/ja_jp.json
@@ -300,6 +300,7 @@
"FieldLock_Error": "",
"FieldLock_Lock_Tooltip": "",
"FieldLock_Locked": "",
+ "FieldLock_SaveBeforeLocking": "",
"FieldLock_Source_Label": "",
"FieldLock_Unlock_Tooltip": "",
"FieldLock_Unlocked": "",
@@ -782,4 +783,4 @@
"settings_system_label": "システム",
"settings_update_item_warning": "以下の値を更新してください。以前のフォーマットに従うよう注意してください。検証は行われません。",
"test_event_tooltip": "設定をテストする前に、まず変更を保存してください。"
-}
+}
\ No newline at end of file
diff --git a/front/php/templates/language/nb_no.json b/front/php/templates/language/nb_no.json
index fa27089e6..70db7f9b8 100644
--- a/front/php/templates/language/nb_no.json
+++ b/front/php/templates/language/nb_no.json
@@ -300,6 +300,7 @@
"FieldLock_Error": "",
"FieldLock_Lock_Tooltip": "",
"FieldLock_Locked": "",
+ "FieldLock_SaveBeforeLocking": "",
"FieldLock_Source_Label": "",
"FieldLock_Unlock_Tooltip": "",
"FieldLock_Unlocked": "",
@@ -782,4 +783,4 @@
"settings_system_label": "System",
"settings_update_item_warning": "Oppdater verdien nedenfor. Pass på å følge forrige format. Validering etterpå utføres ikke.",
"test_event_tooltip": "Lagre endringene først, før du tester innstillingene dine."
-}
+}
\ No newline at end of file
diff --git a/front/php/templates/language/pl_pl.json b/front/php/templates/language/pl_pl.json
index fb4177b32..e0a6d3fdb 100644
--- a/front/php/templates/language/pl_pl.json
+++ b/front/php/templates/language/pl_pl.json
@@ -300,6 +300,7 @@
"FieldLock_Error": "",
"FieldLock_Lock_Tooltip": "",
"FieldLock_Locked": "",
+ "FieldLock_SaveBeforeLocking": "",
"FieldLock_Source_Label": "",
"FieldLock_Unlock_Tooltip": "",
"FieldLock_Unlocked": "",
@@ -782,4 +783,4 @@
"settings_system_label": "System",
"settings_update_item_warning": "Zaktualizuj wartość poniżej. Uważaj, aby zachować poprzedni format. Walidacja nie jest wykonywana.",
"test_event_tooltip": "Najpierw zapisz swoje zmiany, zanim przetestujesz ustawienia."
-}
+}
\ No newline at end of file
diff --git a/front/php/templates/language/pt_br.json b/front/php/templates/language/pt_br.json
index 3940a27c6..64569cdd7 100644
--- a/front/php/templates/language/pt_br.json
+++ b/front/php/templates/language/pt_br.json
@@ -300,6 +300,7 @@
"FieldLock_Error": "",
"FieldLock_Lock_Tooltip": "",
"FieldLock_Locked": "",
+ "FieldLock_SaveBeforeLocking": "",
"FieldLock_Source_Label": "",
"FieldLock_Unlock_Tooltip": "",
"FieldLock_Unlocked": "",
@@ -782,4 +783,4 @@
"settings_system_label": "",
"settings_update_item_warning": "",
"test_event_tooltip": "Guarde as alterações antes de testar as definições."
-}
+}
\ No newline at end of file
diff --git a/front/php/templates/language/pt_pt.json b/front/php/templates/language/pt_pt.json
index 484202f15..c3ad22467 100644
--- a/front/php/templates/language/pt_pt.json
+++ b/front/php/templates/language/pt_pt.json
@@ -300,6 +300,7 @@
"FieldLock_Error": "",
"FieldLock_Lock_Tooltip": "",
"FieldLock_Locked": "",
+ "FieldLock_SaveBeforeLocking": "",
"FieldLock_Source_Label": "",
"FieldLock_Unlock_Tooltip": "",
"FieldLock_Unlocked": "",
@@ -782,4 +783,4 @@
"settings_system_label": "",
"settings_update_item_warning": "",
"test_event_tooltip": "Guarde as alterações antes de testar as definições."
-}
+}
\ No newline at end of file
diff --git a/front/php/templates/language/ru_ru.json b/front/php/templates/language/ru_ru.json
index 760940ce8..4ca53a1b7 100644
--- a/front/php/templates/language/ru_ru.json
+++ b/front/php/templates/language/ru_ru.json
@@ -300,6 +300,7 @@
"FieldLock_Error": "Ошибка при обновлении статуса блокировки поля",
"FieldLock_Lock_Tooltip": "Заблокировать поле (предотвратить перезапись плагином)",
"FieldLock_Locked": "Поле заблокировано",
+ "FieldLock_SaveBeforeLocking": "",
"FieldLock_Source_Label": "Источник: ",
"FieldLock_Unlock_Tooltip": "Разблокировать поле (разрешить перезапись плагином)",
"FieldLock_Unlocked": "Поле разблокировано",
@@ -782,4 +783,4 @@
"settings_system_label": "Система",
"settings_update_item_warning": "Обновить значение ниже. Будьте осторожны, следуя предыдущему формату. Проверка не выполняется.",
"test_event_tooltip": "Сначала сохраните изменения, прежде чем проверять настройки."
-}
+}
\ No newline at end of file
diff --git a/front/php/templates/language/sv_sv.json b/front/php/templates/language/sv_sv.json
index 642ec17af..f76e67299 100644
--- a/front/php/templates/language/sv_sv.json
+++ b/front/php/templates/language/sv_sv.json
@@ -300,6 +300,7 @@
"FieldLock_Error": "",
"FieldLock_Lock_Tooltip": "",
"FieldLock_Locked": "",
+ "FieldLock_SaveBeforeLocking": "",
"FieldLock_Source_Label": "",
"FieldLock_Unlock_Tooltip": "",
"FieldLock_Unlocked": "",
diff --git a/front/php/templates/language/tr_tr.json b/front/php/templates/language/tr_tr.json
index 13075929a..27eeb1774 100644
--- a/front/php/templates/language/tr_tr.json
+++ b/front/php/templates/language/tr_tr.json
@@ -300,6 +300,7 @@
"FieldLock_Error": "",
"FieldLock_Lock_Tooltip": "",
"FieldLock_Locked": "",
+ "FieldLock_SaveBeforeLocking": "",
"FieldLock_Source_Label": "",
"FieldLock_Unlock_Tooltip": "",
"FieldLock_Unlocked": "",
@@ -782,4 +783,4 @@
"settings_system_label": "Sistem",
"settings_update_item_warning": "",
"test_event_tooltip": ""
-}
+}
\ No newline at end of file
diff --git a/front/php/templates/language/uk_ua.json b/front/php/templates/language/uk_ua.json
index 217fe9694..92e799c5d 100644
--- a/front/php/templates/language/uk_ua.json
+++ b/front/php/templates/language/uk_ua.json
@@ -300,6 +300,7 @@
"FieldLock_Error": "Помилка оновлення стану блокування поля",
"FieldLock_Lock_Tooltip": "Заблокувати поле (запобігти перезапису плагіном)",
"FieldLock_Locked": "Поле заблоковано",
+ "FieldLock_SaveBeforeLocking": "",
"FieldLock_Source_Label": "Джерело: ",
"FieldLock_Unlock_Tooltip": "Поле розблокування (дозволити перезапис плагіна)",
"FieldLock_Unlocked": "Поле розблоковано",
@@ -782,4 +783,4 @@
"settings_system_label": "Система",
"settings_update_item_warning": "Оновіть значення нижче. Слідкуйте за попереднім форматом. Перевірка не виконана.",
"test_event_tooltip": "Перш ніж перевіряти налаштування, збережіть зміни."
-}
+}
\ No newline at end of file
diff --git a/front/php/templates/language/zh_cn.json b/front/php/templates/language/zh_cn.json
index 914df988c..7e27c3d83 100644
--- a/front/php/templates/language/zh_cn.json
+++ b/front/php/templates/language/zh_cn.json
@@ -300,6 +300,7 @@
"FieldLock_Error": "",
"FieldLock_Lock_Tooltip": "",
"FieldLock_Locked": "",
+ "FieldLock_SaveBeforeLocking": "",
"FieldLock_Source_Label": "",
"FieldLock_Unlock_Tooltip": "",
"FieldLock_Unlocked": "",
@@ -782,4 +783,4 @@
"settings_system_label": "系统",
"settings_update_item_warning": "更新下面的值。请注意遵循先前的格式。未执行验证。",
"test_event_tooltip": "在测试设置之前,请先保存更改。"
-}
+}
\ No newline at end of file
diff --git a/mkdocs.yml b/mkdocs.yml
index 62ef64e07..8bd37bb1e 100755
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -76,7 +76,7 @@ nav:
- Custom Properties: CUSTOM_PROPERTIES.md
- Device Display Settings: DEVICE_DISPLAY_SETTINGS.md
- Session Info: SESSION_INFO.md
- - Field Lock/Unlock: QUICK_REFERENCE_FIELD_LOCK.md
+ - Field Lock/Unlock: DEVICE_FIELD_LOCK.md
- Icons and Topology:
- Icons: ICONS.md
- Network Topology: NETWORK_TREE.md
diff --git a/server/models/device_instance.py b/server/models/device_instance.py
index 3b243a747..6037ab7f5 100755
--- a/server/models/device_instance.py
+++ b/server/models/device_instance.py
@@ -429,7 +429,8 @@ class DeviceInstance:
"devDownAlerts": 0,
"devPresenceHours": 0,
"devFQDN": "",
- "devForceStatus" : "dont_force"
+ "devForceStatus" : "dont_force",
+ "devVlan": ""
}
return device_data
@@ -536,7 +537,8 @@ class DeviceInstance:
"devIsNew",
"devIsArchived",
"devCustomProps",
- "devForceStatus"
+ "devForceStatus",
+ "devVlan"
}
# Only mark USER for tracked fields that this method actually updates.
@@ -586,8 +588,8 @@ class DeviceInstance:
devParentRelType, devReqNicsOnline, devSkipRepeated,
devIsNew, devIsArchived, devLastConnection,
devFirstConnection, devLastIP, devGUID, devCustomProps,
- devSourcePlugin, devForceStatus
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+ devSourcePlugin, devForceStatus, devVlan
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
"""
values = (
@@ -621,6 +623,7 @@ class DeviceInstance:
data.get("devCustomProps") or "",
data.get("devSourcePlugin") or "DUMMY",
data.get("devForceStatus") or "dont_force",
+ data.get("devVlan") or "",
)
else:
@@ -631,7 +634,7 @@ class DeviceInstance:
devParentMAC=?, devParentPort=?, devSSID=?, devSite=?,
devStaticIP=?, devScan=?, devAlertEvents=?, devAlertDown=?,
devParentRelType=?, devReqNicsOnline=?, devSkipRepeated=?,
- devIsNew=?, devIsArchived=?, devCustomProps=?, devForceStatus=?
+ devIsNew=?, devIsArchived=?, devCustomProps=?, devForceStatus=?, devVlan=?
WHERE devMac=?
"""
values = (
@@ -659,6 +662,7 @@ class DeviceInstance:
data.get("devIsArchived") or 0,
data.get("devCustomProps") or "",
data.get("devForceStatus") or "dont_force",
+ data.get("devVlan") or "",
normalized_mac,
)
diff --git a/test/authoritative_fields/FIELD_LOCK_TEST_SUMMARY.md b/test/authoritative_fields/FIELD_LOCK_TEST_SUMMARY.md
index 2259f5fa8..3adcbdb69 100644
--- a/test/authoritative_fields/FIELD_LOCK_TEST_SUMMARY.md
+++ b/test/authoritative_fields/FIELD_LOCK_TEST_SUMMARY.md
@@ -165,20 +165,20 @@ def test_scenario():
```python
def test_scan_scenario(scan_db, mock_device_handlers):
cur = scan_db.cursor()
-
+
# Insert device with specific source
cur.execute("INSERT INTO Devices ...")
-
+
# Insert scan results
cur.execute("INSERT INTO CurrentScan ...")
scan_db.commit()
-
+
# Run actual scan update
db = Mock()
db.sql_connection = scan_db
db.sql = cur
device_handling.update_devices_data_from_scan(db)
-
+
# Verify results
row = cur.execute("SELECT ... FROM Devices")
assert row["field"] == "expected_value"
@@ -246,7 +246,7 @@ All 10 lockable fields tested:
5. **Rule 5 (Default):** If current_source is empty/"NEWDEV" → Return `True`, else → Return `False`
- Default behavior: only overwrite empty/unset fields
-**Key Principles:**
+**Key Principles:**
- **USER and LOCKED** = Absolute protection (cannot be overwritten, even with SET_ALWAYS)
- **SET_ALWAYS** = Allow overwrite of: own fields, other plugin fields, empty current values, NEWDEV fields
- **SET_EMPTY** = "Set only if empty" - fills empty fields only, won't overwrite existing plugin data
@@ -257,7 +257,7 @@ All 10 lockable fields tested:
## Related Documentation
-- **User Guide:** [QUICK_REFERENCE_FIELD_LOCK.md](../../docs/QUICK_REFERENCE_FIELD_LOCK.md) - User-friendly field locking instructions
+- **User Guide:** [DEVICE_FIELD_LOCK.md](../../docs/DEVICE_FIELD_LOCK.md) - User-friendly field locking instructions
- **API Documentation:** [API_DEVICE_FIELD_LOCK.md](../../docs/API_DEVICE_FIELD_LOCK.md) - Endpoint documentation
- **Plugin Configuration:** [PLUGINS_DEV_CONFIG.md](../../docs/PLUGINS_DEV_CONFIG.md) - SET_ALWAYS/SET_EMPTY configuration guide
- **Device Management:** [DEVICE_MANAGEMENT.md](../../docs/DEVICE_MANAGEMENT.md) - Device management admin guide