Auto-commit local changes before build (2026-03-20 15:09:58)
This commit is contained in:
parent
5fdf0f130b
commit
7ae04c59fe
@ -2,6 +2,7 @@ from .routes_shared import * # noqa: F401,F403
|
|||||||
from .routes_shared import _get_database_size_bytes, _get_or_create_settings, _format_bytes, _get_free_disk_bytes, _log_admin_event
|
from .routes_shared import _get_database_size_bytes, _get_or_create_settings, _format_bytes, _get_free_disk_bytes, _log_admin_event
|
||||||
import json
|
import json
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from ..models import CoveAccount, CloudConnectAccount
|
||||||
|
|
||||||
@main_bp.route("/settings/jobs/delete-all", methods=["POST"])
|
@main_bp.route("/settings/jobs/delete-all", methods=["POST"])
|
||||||
@login_required
|
@login_required
|
||||||
@ -451,7 +452,7 @@ def settings_jobs_export():
|
|||||||
try:
|
try:
|
||||||
jobs = Job.query.all()
|
jobs = Job.query.all()
|
||||||
payload = {
|
payload = {
|
||||||
"schema": "approved_jobs_export_v1",
|
"schema": "approved_jobs_export_v2",
|
||||||
"exported_at": datetime.utcnow().isoformat() + "Z",
|
"exported_at": datetime.utcnow().isoformat() + "Z",
|
||||||
"counts": {"customers": 0, "jobs": 0},
|
"counts": {"customers": 0, "jobs": 0},
|
||||||
"customers": [],
|
"customers": [],
|
||||||
@ -475,6 +476,25 @@ def settings_jobs_export():
|
|||||||
|
|
||||||
for job in jobs:
|
for job in jobs:
|
||||||
customer = customer_by_id.get(job.customer_id)
|
customer = customer_by_id.get(job.customer_id)
|
||||||
|
|
||||||
|
cove_acc = getattr(job, "cove_account", None)
|
||||||
|
cove_data = None
|
||||||
|
if cove_acc:
|
||||||
|
cove_data = {
|
||||||
|
"account_id": cove_acc.account_id,
|
||||||
|
"account_name": cove_acc.account_name or "",
|
||||||
|
"computer_name": cove_acc.computer_name or "",
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_acc = getattr(job, "cloud_connect_account", None)
|
||||||
|
cc_data = None
|
||||||
|
if cc_acc:
|
||||||
|
cc_data = {
|
||||||
|
"user": cc_acc.user or "",
|
||||||
|
"section": cc_acc.section or "",
|
||||||
|
"repo_name": cc_acc.repo_name or "",
|
||||||
|
}
|
||||||
|
|
||||||
payload["jobs"].append(
|
payload["jobs"].append(
|
||||||
{
|
{
|
||||||
"customer_name": customer.name if customer else None,
|
"customer_name": customer.name if customer else None,
|
||||||
@ -488,6 +508,8 @@ def settings_jobs_export():
|
|||||||
"schedule_times": job.schedule_times,
|
"schedule_times": job.schedule_times,
|
||||||
"auto_approve": bool(job.auto_approve),
|
"auto_approve": bool(job.auto_approve),
|
||||||
"active": bool(job.active),
|
"active": bool(job.active),
|
||||||
|
"cove_account": cove_data,
|
||||||
|
"cloud_connect_account": cc_data,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -500,7 +522,7 @@ def settings_jobs_export():
|
|||||||
f"Exported jobs configuration",
|
f"Exported jobs configuration",
|
||||||
details=json.dumps({
|
details=json.dumps({
|
||||||
"format": "JSON",
|
"format": "JSON",
|
||||||
"schema": "approved_jobs_export_v1",
|
"schema": "approved_jobs_export_v2",
|
||||||
"customers_count": len(payload["customers"]),
|
"customers_count": len(payload["customers"]),
|
||||||
"jobs_count": len(payload["jobs"])
|
"jobs_count": len(payload["jobs"])
|
||||||
}, indent=2)
|
}, indent=2)
|
||||||
@ -537,7 +559,7 @@ def settings_jobs_import():
|
|||||||
flash("Invalid JSON file.", "danger")
|
flash("Invalid JSON file.", "danger")
|
||||||
return redirect(url_for("main.settings", section="general"))
|
return redirect(url_for("main.settings", section="general"))
|
||||||
|
|
||||||
if not isinstance(payload, dict) or payload.get("schema") != "approved_jobs_export_v1":
|
if not isinstance(payload, dict) or payload.get("schema") not in ("approved_jobs_export_v1", "approved_jobs_export_v2"):
|
||||||
flash("Unsupported import file schema.", "danger")
|
flash("Unsupported import file schema.", "danger")
|
||||||
return redirect(url_for("main.settings", section="general"))
|
return redirect(url_for("main.settings", section="general"))
|
||||||
|
|
||||||
@ -669,6 +691,7 @@ def settings_jobs_import():
|
|||||||
existing.auto_approve = auto_approve
|
existing.auto_approve = auto_approve
|
||||||
existing.active = active
|
existing.active = active
|
||||||
updated_jobs += 1
|
updated_jobs += 1
|
||||||
|
job_record = existing
|
||||||
else:
|
else:
|
||||||
job_kwargs = {
|
job_kwargs = {
|
||||||
"customer_id": (customer.id if customer else None),
|
"customer_id": (customer.id if customer else None),
|
||||||
@ -687,7 +710,41 @@ def settings_jobs_import():
|
|||||||
job_kwargs["from_address"] = from_address
|
job_kwargs["from_address"] = from_address
|
||||||
new_job = Job(**job_kwargs)
|
new_job = Job(**job_kwargs)
|
||||||
db.session.add(new_job)
|
db.session.add(new_job)
|
||||||
|
db.session.flush()
|
||||||
created_jobs += 1
|
created_jobs += 1
|
||||||
|
job_record = new_job
|
||||||
|
|
||||||
|
# Link Cove account if present in export and not already linked to another job
|
||||||
|
cove_data = item.get("cove_account")
|
||||||
|
if cove_data and isinstance(cove_data, dict):
|
||||||
|
try:
|
||||||
|
cove_acc = None
|
||||||
|
if cove_data.get("account_id") is not None:
|
||||||
|
cove_acc = CoveAccount.query.filter_by(account_id=int(cove_data["account_id"])).first()
|
||||||
|
if cove_acc is None and cove_data.get("account_name") and cove_data.get("computer_name"):
|
||||||
|
cove_acc = CoveAccount.query.filter_by(
|
||||||
|
account_name=cove_data["account_name"],
|
||||||
|
computer_name=cove_data["computer_name"],
|
||||||
|
).first()
|
||||||
|
if cove_acc and (cove_acc.job_id is None or cove_acc.job_id == job_record.id):
|
||||||
|
cove_acc.job_id = job_record.id
|
||||||
|
job_record.cove_account_id = cove_acc.account_id
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Link Cloud Connect account if present in export and not already linked to another job
|
||||||
|
cc_data = item.get("cloud_connect_account")
|
||||||
|
if cc_data and isinstance(cc_data, dict):
|
||||||
|
try:
|
||||||
|
cc_acc = CloudConnectAccount.query.filter_by(
|
||||||
|
user=cc_data.get("user", ""),
|
||||||
|
section=cc_data.get("section", ""),
|
||||||
|
repo_name=cc_data.get("repo_name", ""),
|
||||||
|
).first()
|
||||||
|
if cc_acc and (cc_acc.job_id is None or cc_acc.job_id == job_record.id):
|
||||||
|
cc_acc.job_id = job_record.id
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash(
|
flash(
|
||||||
|
|||||||
@ -2,6 +2,13 @@
|
|||||||
|
|
||||||
This file documents all changes made to this project via Claude Code.
|
This file documents all changes made to this project via Claude Code.
|
||||||
|
|
||||||
|
## [2026-03-20] (8)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Jobs export/import now includes Cove and Cloud Connect account links (schema bumped to `approved_jobs_export_v2`):
|
||||||
|
- **Export**: each job entry now contains a `cove_account` object (`account_id`, `account_name`, `computer_name`) and a `cloud_connect_account` object (`user`, `section`, `repo_name`) when linked; `null` when not linked
|
||||||
|
- **Import**: accepts both `v1` (no linking) and `v2` files; for `v2` files, after creating/updating the job the importer looks up the matching `CoveAccount` by `account_id` (fallback: `account_name` + `computer_name`) and the matching `CloudConnectAccount` by `user` + `section` + `repo_name`, and links them to the job — only if the account is not yet linked to a different job
|
||||||
|
|
||||||
## [2026-03-20] (7)
|
## [2026-03-20] (7)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user