Add configuration revisions system and project variant deletion

Features:
- Configuration versioning: immutable snapshots in local_configuration_versions
- Revisions UI: /configs/:uuid/revisions page to view version history
- Clone from version: ability to clone configuration from specific revision
- Project variant deletion: DELETE /api/projects/:uuid endpoint
- Updated CLAUDE.md with new architecture details and endpoints

Architecture updates:
- local_configuration_versions table for immutable snapshots
- Version tracking on each configuration save
- Rollback capability to previous versions
- Variant deletion with main variant protection

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-16 22:30:33 +03:00
parent 8508ee2921
commit 2e973b6d78
10 changed files with 407 additions and 17 deletions

View File

@@ -20,7 +20,9 @@
<span id="breadcrumb-project-variant">main</span>
</a>
<span class="text-gray-400">-</span>
<span id="breadcrumb-config-name">Конфигуратор</span>
<a id="breadcrumb-config-name-link" href="#" class="text-blue-700 hover:underline">
<span id="breadcrumb-config-name">Конфигуратор</span>
</a>
<span class="text-gray-400">-</span>
<span id="breadcrumb-config-version">v1</span>
</div>
@@ -338,6 +340,7 @@ let ASSIGNED_CATEGORIES = Object.values(TAB_CONFIG)
// State
let configUUID = '{{.ConfigUUID}}';
let configName = '';
let currentVersionNo = 1;
let projectUUID = '';
let projectName = '';
let projectCode = '';
@@ -399,7 +402,11 @@ function updateConfigBreadcrumbs() {
codeEl.textContent = code;
variantEl.textContent = variant;
configEl.textContent = configName || 'Конфигурация';
versionEl.textContent = 'v1';
versionEl.textContent = 'v' + (currentVersionNo || 1);
const configNameLinkEl = document.getElementById('breadcrumb-config-name-link');
if (configNameLinkEl && configUUID) {
configNameLinkEl.href = '/configs/' + configUUID + '/revisions';
}
}
let currentTab = 'base';
let allComponents = [];
@@ -688,6 +695,7 @@ document.addEventListener('DOMContentLoaded', async function() {
const config = await resp.json();
configName = config.name;
currentVersionNo = config.current_version_no || 1;
projectUUID = config.project_uuid || '';
await loadProjectIndex();
updateConfigBreadcrumbs();
@@ -1937,6 +1945,13 @@ async function saveConfig(showNotification = true) {
return;
}
const saved = await resp.json();
if (saved && saved.current_version_no) {
currentVersionNo = saved.current_version_no;
const versionEl = document.getElementById('breadcrumb-config-version');
if (versionEl) versionEl.textContent = 'v' + currentVersionNo;
}
if (showNotification) {
showToast('Сохранено', 'success');
}