P4 Software / cifraHQ

P4Books Migration

Migrate a P4Books Tenant Into CifraHQ

If your organization is moving from the legacy P4Books product to CifraHQ, you can import an existing P4Books export zip and have a fully working CifraHQ tenant on the other side. The import does everything in one step: it restores the SQL data, brings the database schema up to the current CifraHQ baseline, restores the audit and metadata collections, and re-uploads every binary attachment (logos, product photos, document scans) into your tenant's secure blob storage.

This page covers the import workflow. Only super-admins can run it.

When to use this

Run this import when:

  • A customer hands you a P4Books export zip (typically generated by the legacy product's Tenant Export action) and you want to spin them up on CifraHQ.
  • You want to stand up a parallel test tenant from an existing P4Books snapshot without touching the live tenant.

Do not use this for routine backups between CifraHQ tenants: the Tenant Export and Tenant Import actions in the Admin Console handle CifraHQ-to-CifraHQ moves directly without any schema conversion.

What's inside a P4Books export zip

A P4Books export contains four kinds of payload:

Item Purpose
tenant.json Tenant metadata: company name, alias, tax id, time zone, logo.
{alias}.bacpac SQL Server backup of the tenant database. Uses the legacy P4Books schema lineage.
P4B_{alias}/*.bson MongoDB dumps for History, CallLocks, and Files metadata.
files/{32-char-id} The binary contents of every uploaded file (mostly product photos and PDF attachments), one per file id.

The import understands all four payloads. You do not need to extract the zip or pre-process it.

Step-by-step

Step 1. Host the export zip somewhere CifraHQ can reach

The import accepts the zip via URL, not direct file upload. The simplest path is to upload the zip to your tenant's Azure Blob container or to any other HTTPS location that Returns the raw bytes when fetched. A short-lived Shared Access Signature URL works fine: the import downloads the file and discards the URL afterward.

The URL must be reachable from the CifraHQ application servers, return content-type application/zip, and not require interactive authentication.

Step 2. Open the Admin Console

Sign in to https://app.CifraHQ.cloud/admin with a super-admin account. From the Tenants page, click the top-right action menu and choose Import Tenant.

Step 3. Pick the new tenant alias

CifraHQ will prompt for a new tenant alias. Type the alias you want this tenant to use going forward. The alias must be:

  • Unique across all CifraHQ tenants
  • Lowercase letters and digits only
  • Short enough to feel natural as a subdomain, since the tenant will live at https://{alias}.CifraHQ.cloud

If the customer was previously known as nerv in P4Books, you can keep nerv as the alias, or pick something different like nerv-prod or nervlive. The original alias inside the zip is rewritten to the value you type here, so there is no naming collision with the source export.

Step 4. Paste the package URL

Paste the URL you prepared in Step 1 and click Import.

Step 5. Watch the progress log

A progress dialog opens and streams the import in real time via SignalR. Expect to see roughly the following lines, in order:

Reading archive...
Creating tenant record...
Extracting database...
Detected P4Books migration lineage. Applying upgrade SQL...
P4Books upgrade applied (N batches).
Migrating database...
Priming tenant...
Extracting mongo...
Rehydrating N binary files into blob storage...
Rehydrated N binary files.
Done.

For a typical small tenant (a few hundred Products and a few hundred attachments) the whole import completes in two to five minutes. Larger tenants scale roughly linearly with the BACPAC size and the number of binary files.

If the run fails partway, the entire transaction is rolled back: the tenant record, the database, and any Mongo data are removed so you can try again with a clean slate.

Imported tenants are created with no license attached. Before you hand the tenant over to the customer, go to https://p4licenses.cloud/ and link the new tenant to a subscription. Without this step the tenant signs in but the license check fails and most pages refuse to load.

Step 7. Reset administrator passwords

The import preserves all user records from the source P4Books database, but it does not preserve hashed passwords for the built-in administrator accounts. Sign in as the system administrator using the recovery flow (or have the customer use the password reset email), then re-enable normal Users from the Users screen.

Step 8. Smoke test

Open https://{alias}.CifraHQ.cloud in a private window. Confirm:

  • The login page renders (no 500 error).
  • After login, the dashboard loads.
  • A product detail page shows its photo without a broken image icon. This is the visible proof that the binary rehydrate succeeded.
  • The customer's Master Data (Vendors, Customers, Products) is present and the counts roughly match the source P4Books install.

What the import does behind the scenes

This section is for super-admins who want to understand the conversion. Skip it if you only care about running the import.

  1. Tenant record: tenant.json is read and a fresh row is created in the master Tenants table with the alias you supplied. The license fields are cleared so the tenant cannot start serving requests until a license is linked.
  2. SQL restore: {alias}.bacpac is restored into a brand-new CHQ_{alias} database via Azure SQL BACPAC import.
  3. P4Books schema upgrade: the restored database is inspected for the legacy Init1...Init57 migration history rows. If found, the same validated upgrade SQL script that CifraHQ engineering has been applying by hand for a year (see Docs/db-upgrade/upgrade-p4books-to-CifraHQ.sql) is executed inline. It clears the legacy migration rows, inserts the CifraHQ baseline rows, creates five tables that did not exist in P4Books, and patches UserDefinedFields schema drift. The script is idempotent: running it on a database that is already on CifraHQ lineage is a no-op.
  4. EF migrations: dotnet ef database update equivalent runs against the database to apply every CifraHQ delta migration that came after the baseline.
  5. Mongo restore: mongorestore reads the BSON dumps and rebuilds the History, CallLocks, and Files metadata collections under the new alias on the shared p4smongo cluster.
  6. Binary rehydrate: the files/ directory is walked file by file. Each blob is uploaded to the new tenant's Azure Blob container with the original 32-character hex id preserved as the blob name, so every SQL record that references that id still resolves. Content type is detected from PNG, JPEG, GIF, WebP, and PDF magic bytes.
  7. Prime: built-in service accounts are reset with fresh API keys and the transaction commits.

Troubleshooting

Import fails at "Extracting database..." with a BACPAC error. The zip is incomplete or the BACPAC inside it was generated against a SQL Server version newer than CifraHQ's target. Re-export from the source system and retry.

Progress log stops at "Rehydrating..." and never Returns. The Azure Blob connection string is missing or the application identity does not have write permission on the tenant's container. Check the app service configuration for the BinaryStorage connection string.

Products show no photos after import even though the import completed. The files/ directory was empty in the zip. The source P4Books installation likely stored photos elsewhere (a different file root). Contact engineering with the export source so the path can be located and re-attached.

Login works but every page shows "No license". Step 6 was skipped. Link the tenant to a subscription at https://p4licenses.cloud/ and retry.


Related: Database Backups - Tenant Configuration - Modules

Was this page helpful?