mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 04:08:11 +00:00
feat: enhance onboarding process and company profile management
- Updated CompanyInfoResponseDto to include company profile data in response. - Enhanced ResponseExternalProfileDto to include active profile type and onboarding details. - Added new fields to ExternalProfile entity for active profile type and onboarding status. - Implemented onboarding wizard dialog in the frontend to guide users through the onboarding process. - Introduced API endpoints for managing company profiles and onboarding steps. - Created migrations to add new columns for active mode and onboarding status in the database. - Added functionality to switch between operational modes (importer/exporter) and create profiles as needed. - Improved user experience by ensuring onboarding is enforced for new users and those without completed profiles.
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
export class AddActiveModeAndOnboardingToExternalProfiles1791000000000
|
||||
implements MigrationInterface
|
||||
{
|
||||
name = 'AddActiveModeAndOnboardingToExternalProfiles1791000000000';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE freight.external_profiles
|
||||
ADD COLUMN IF NOT EXISTS active_profile_type varchar(32);
|
||||
`);
|
||||
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE freight.external_profiles
|
||||
ADD COLUMN IF NOT EXISTS onboarding_step varchar(40);
|
||||
`);
|
||||
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE freight.external_profiles
|
||||
ADD COLUMN IF NOT EXISTS onboarding_completed boolean NOT NULL DEFAULT false;
|
||||
`);
|
||||
|
||||
// Existing users already use the portal — never re-gate them behind the
|
||||
// new onboarding wizard.
|
||||
await queryRunner.query(`
|
||||
UPDATE freight.external_profiles
|
||||
SET onboarding_completed = true
|
||||
WHERE onboarding_completed = false;
|
||||
`);
|
||||
|
||||
// Backfill the active mode for existing users from their company's
|
||||
// operational profiles. Prefer importer, then exporter, then whichever
|
||||
// single profile the company has (forwarder/dj/transporter).
|
||||
await queryRunner.query(`
|
||||
UPDATE freight.external_profiles ep
|
||||
SET active_profile_type = cp.type
|
||||
FROM (
|
||||
SELECT DISTINCT ON (company_id) company_id, type
|
||||
FROM freight.company_profiles
|
||||
ORDER BY company_id,
|
||||
CASE type
|
||||
WHEN 'importer' THEN 0
|
||||
WHEN 'exporter' THEN 1
|
||||
ELSE 2
|
||||
END
|
||||
) cp
|
||||
WHERE ep.company_id = cp.company_id
|
||||
AND ep.active_profile_type IS NULL;
|
||||
`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE freight.external_profiles
|
||||
DROP COLUMN IF EXISTS onboarding_completed;
|
||||
`);
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE freight.external_profiles
|
||||
DROP COLUMN IF EXISTS onboarding_step;
|
||||
`);
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE freight.external_profiles
|
||||
DROP COLUMN IF EXISTS active_profile_type;
|
||||
`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
export class AddCompanyProfileIdToBookings1791000000001
|
||||
implements MigrationInterface
|
||||
{
|
||||
name = 'AddCompanyProfileIdToBookings1791000000001';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE freight.bookings
|
||||
ADD COLUMN IF NOT EXISTS company_profile_id UUID;
|
||||
`);
|
||||
|
||||
await queryRunner.query(`
|
||||
CREATE INDEX IF NOT EXISTS idx_bookings_company_profile_id
|
||||
ON freight.bookings(company_profile_id);
|
||||
`);
|
||||
|
||||
await queryRunner.query(`
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'FK_bookings_company_profile_id'
|
||||
) THEN
|
||||
ALTER TABLE freight.bookings
|
||||
ADD CONSTRAINT "FK_bookings_company_profile_id"
|
||||
FOREIGN KEY (company_profile_id)
|
||||
REFERENCES freight.company_profiles(id);
|
||||
END IF;
|
||||
END $$;
|
||||
`);
|
||||
|
||||
// Backfill by natural mapping: IMPORT → importer profile, EXPORT → exporter
|
||||
// profile, for each booking's own company.
|
||||
await queryRunner.query(`
|
||||
UPDATE freight.bookings b
|
||||
SET company_profile_id = cp.id
|
||||
FROM freight.company_profiles cp
|
||||
WHERE cp.company_id = b.company_id
|
||||
AND b.company_profile_id IS NULL
|
||||
AND (
|
||||
(b.trade_direction = 'IMPORT' AND cp.type = 'importer') OR
|
||||
(b.trade_direction = 'EXPORT' AND cp.type = 'exporter')
|
||||
);
|
||||
`);
|
||||
|
||||
// Forwarder / single-profile companies: one profile per company, so the
|
||||
// mapping is unambiguous regardless of trade direction.
|
||||
await queryRunner.query(`
|
||||
UPDATE freight.bookings b
|
||||
SET company_profile_id = cp.id
|
||||
FROM freight.company_profiles cp
|
||||
JOIN freight.companies c ON c.id = cp.company_id
|
||||
WHERE cp.company_id = b.company_id
|
||||
AND c.type <> 'customer'
|
||||
AND b.company_profile_id IS NULL;
|
||||
`);
|
||||
|
||||
// Remaining customer-owned rows (e.g. DOMESTIC, or a direction with no
|
||||
// matching profile): attribute to the company's importer profile, else its
|
||||
// exporter profile, so nothing disappears from the customer's list.
|
||||
await queryRunner.query(`
|
||||
UPDATE freight.bookings b
|
||||
SET company_profile_id = cp.id
|
||||
FROM (
|
||||
SELECT DISTINCT ON (company_id) company_id, id
|
||||
FROM freight.company_profiles
|
||||
ORDER BY company_id,
|
||||
CASE type
|
||||
WHEN 'importer' THEN 0
|
||||
WHEN 'exporter' THEN 1
|
||||
ELSE 2
|
||||
END
|
||||
) cp
|
||||
WHERE cp.company_id = b.company_id
|
||||
AND b.company_id IS NOT NULL
|
||||
AND b.company_profile_id IS NULL;
|
||||
`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE freight.bookings
|
||||
DROP CONSTRAINT IF EXISTS "FK_bookings_company_profile_id";
|
||||
`);
|
||||
await queryRunner.query(`
|
||||
DROP INDEX IF EXISTS freight.idx_bookings_company_profile_id;
|
||||
`);
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE freight.bookings
|
||||
DROP COLUMN IF EXISTS company_profile_id;
|
||||
`);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user