wip: ops admin panel + migration sync + crud/rbac phase-5 snapshot

Working-tree checkpoint of in-progress work carried across prior
sessions on the feat/crud-rbac branch, committed so it lands on the
remote alongside the CI changes.

- Operaciones admin panel: apps/api/src/ops (ingest upload, backup /
  restore / re-import jobs) wired into app.module + RBAC abilities, and
  the apps/web/src/app/operaciones page. docker-compose gets INGEST_DIR
  / BACKUP_DIR volumes; .gitignore excludes migration/ingest + backups.
- migration/sync.py plus transform_*.py / run_all / config / dbenv /
  blob_extract adjustments for the additive sync path.
- crud/rbac phase-5 web bits: AppShell, api/labels/types libs, globals.
- schema.prisma + PLAN/RESUME doc updates.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-23 19:01:36 -07:00
co-authored by Claude Opus 4.8
parent 6ad0993a71
commit f1ef1c70b3
27 changed files with 1480 additions and 107 deletions
+41
View File
@@ -224,6 +224,7 @@ model Vehicle {
legacySourceTable String?
legacyId String?
@@unique([legacySourceTable, legacyId])
@@map("vehicles")
}
@@ -331,6 +332,7 @@ model Property {
documents ServiceDocument[]
trustAccount TrustAccount?
@@unique([legacySourceTable, legacyId])
@@map("properties")
}
@@ -420,6 +422,7 @@ model Transaction {
createdAt DateTime @default(now())
@@index([customerId, transactionDate])
@@unique([legacySourceDb, legacySourceTable, legacyId])
@@map("transactions")
}
@@ -468,6 +471,7 @@ model BankTransaction {
legacySourceTable String?
legacyId String?
@@unique([legacySourceTable, legacyId])
@@map("bank_transactions")
}
@@ -533,3 +537,40 @@ model EmailLog {
@@map("email_log")
}
// ---------------------------------------------------------------------------
// Admin database operations (Operaciones): backup / restore / re-import / sync.
// Each long-running op is one OpsJob row so the web UI can poll status + tail
// the captured log. Rows are the audit trail for who ran a destructive op.
// ---------------------------------------------------------------------------
enum OpsJobKind {
BACKUP
RESTORE
REIMPORT
SYNC
}
enum OpsJobStatus {
RUNNING
SUCCESS
FAILED
}
model OpsJob {
id String @id @default(uuid())
kind OpsJobKind
status OpsJobStatus @default(RUNNING)
// Combined stdout+stderr of the spawned process, appended as it runs.
log String @db.LongText
// Op-specific inputs (e.g. the backup filename a RESTORE targets). No FK on
// createdById — the actor id is stored flat, like activity_logs' userId use.
params Json?
createdById String?
startedAt DateTime @default(now())
finishedAt DateTime?
@@index([status])
@@index([startedAt])
@@map("ops_jobs")
}