-- Test users for the freight e2e stack — replicates what the (disabled) -- FreightStaffUsersSeeder + DemoUsersSeeder would write, without touching -- API code. Idempotent: every insert is guarded by WHERE NOT EXISTS. -- -- Prerequisites (created by the API's always-on boot seeders): -- iam.organizations key='edr_freight', iam.units key='edr_freight_app', -- iam.positions keys ceo/chief/director/marketer/operation/ethiopian_gl/djibouti_gl. -- -- Passwords are pre-hashed (argon2id): -- staff (@edr.local) → password@tria -- demo (gmail.com) → 12345678 -- ── Demo organization ──────────────────────────────────────────────────────── insert into iam.organizations (id, name, key, is_super_admin, is_government_organization, status) select gen_random_uuid(), '{"en":"Demo IAM"}'::jsonb, 'demo_iam', false, true, 'Active' where not exists (select 1 from iam.organizations where key = 'demo_iam'); -- ── Roles ──────────────────────────────────────────────────────────────────── insert into iam.roles (id, key, name) select gen_random_uuid(), v.key, jsonb_build_object('en', v.name) from (values ('edr_line_staff', 'edr_line_staff'), ('edr_org_manager', 'edr_org_manager'), ('edr_director', 'edr_director'), ('edr_ceo', 'edr_ceo'), ('edr_marketing', 'edr_marketing'), ('edr_operations_officer', 'edr_operations_officer'), ('edr_gl_ethiopia', 'edr_gl_ethiopia'), ('edr_gl_djibouti', 'edr_gl_djibouti'), ('demo_user1', 'Demo User1'), ('demo_user2', 'Demo User2') ) v(key, name) where not exists (select 1 from iam.roles r where r.key = v.key); -- ── Demo permissions + role grants ─────────────────────────────────────────── insert into iam.permissions (id, key, name) select gen_random_uuid(), v.key, jsonb_build_object('en', v.name) from (values ('can:demo:user1', 'Can access demo user1'), ('can:demo:user2', 'Can access demo user2') ) v(key, name) where not exists (select 1 from iam.permissions p where p.key = v.key); insert into iam.role_permissions (id, role_id, permission_id) select gen_random_uuid(), r.id, p.id from (values ('demo_user1', 'can:demo:user1'), ('demo_user2', 'can:demo:user2')) v(role_key, perm_key) join iam.roles r on r.key = v.role_key join iam.permissions p on p.key = v.perm_key where not exists ( select 1 from iam.role_permissions rp where rp.role_id = r.id and rp.permission_id = p.id ); -- ── Users ──────────────────────────────────────────────────────────────────── insert into iam.users (id, email, username, name, status, is_active, has_set_password, user_type) select gen_random_uuid(), v.email, v.username, jsonb_build_object('en', v.display), 'accepted', true, true, 'employee' from (values ('linestaff@edr.local', 'linestaff', 'linestaff'), ('chief@edr.local', 'chief', 'chief'), ('director@edr.local', 'director', 'director'), ('ceo@edr.local', 'ceo', 'ceo'), ('marketer@edr.local', 'marketer', 'marketer'), ('operation@edr.local', 'operation', 'operation'), ('gl-et@edr.local', 'gl_et', 'gl_et'), ('gl-dj@edr.local', 'gl_dj', 'gl_dj'), ('user@gmail.com', 'user', 'Demo User 1'), ('user2@gmail.com', 'user2', 'Demo User 2') ) v(email, username, display) where not exists (select 1 from iam.users u where u.email = v.email); -- ── Credentials ────────────────────────────────────────────────────────────── insert into iam.user_credentials (id, user_id, password, is_active) select gen_random_uuid(), u.id, case when u.email like '%@edr.local' then '$argon2id$v=19$m=65536,t=3,p=4$JFEcHu4Kp55fsrVDPbHDPg$0NfnGzaE39T/qdmzte73oCkohC0Ri+f8DcrvAF4kyH4' -- password@tria else '$argon2id$v=19$m=65536,t=3,p=4$aBwVFf7I74pqSJqe9cBoig$gCIKa+6dCAb2X86G+0IjgPtil127cx6A6mwhvLj00Bw' -- 12345678 end, true from iam.users u where (u.email like '%@edr.local' or u.email in ('user@gmail.com', 'user2@gmail.com')) and not exists (select 1 from iam.user_credentials c where c.user_id = u.id); -- ── User → role (staff under edr_freight, demo under demo_iam) ────────────── insert into iam.user_roles (id, user_id, role_id, organization_id) select gen_random_uuid(), u.id, r.id, o.id from (values ('linestaff@edr.local', 'edr_line_staff', 'edr_freight'), ('chief@edr.local', 'edr_org_manager', 'edr_freight'), ('director@edr.local', 'edr_director', 'edr_freight'), ('ceo@edr.local', 'edr_ceo', 'edr_freight'), ('marketer@edr.local', 'edr_marketing', 'edr_freight'), ('operation@edr.local', 'edr_operations_officer', 'edr_freight'), ('gl-et@edr.local', 'edr_gl_ethiopia', 'edr_freight'), ('gl-dj@edr.local', 'edr_gl_djibouti', 'edr_freight'), ('user@gmail.com', 'demo_user1', 'demo_iam'), ('user2@gmail.com', 'demo_user2', 'demo_iam') ) v(email, role_key, org_key) join iam.users u on u.email = v.email join iam.roles r on r.key = v.role_key join iam.organizations o on o.key = v.org_key where not exists (select 1 from iam.user_roles ur where ur.user_id = u.id and ur.role_id = r.id); -- ── Staff employees + position assignment (drives permissions) ─────────────── insert into iam.employees (id, is_current, status, name, organization_id, unit_id, user_id) select gen_random_uuid(), true, 'pending', u.name, o.id, un.id, u.id from iam.users u join iam.organizations o on o.key = 'edr_freight' join iam.units un on un.key = 'edr_freight_app' and un.organization_id = o.id where u.email like '%@edr.local' and not exists (select 1 from iam.employees e where e.user_id = u.id); -- start_date must be set: the login query filters positions on -- start_date <= NOW(), and a NULL start_date silently drops the position -- (and with it every permission) from the JWT. insert into iam.employee_positions (id, is_delegate, is_current, status, start_date, unit_id, employee_id, position_id) select gen_random_uuid(), false, true, 'APPROVED', now() - interval '1 day', un.id, e.id, p.id from (values ('linestaff@edr.local', 'operation'), ('chief@edr.local', 'chief'), ('director@edr.local', 'director'), ('ceo@edr.local', 'ceo'), ('marketer@edr.local', 'marketer'), ('operation@edr.local', 'operation'), ('gl-et@edr.local', 'ethiopian_gl'), ('gl-dj@edr.local', 'djibouti_gl') ) v(email, position_key) join iam.users u on u.email = v.email join iam.employees e on e.user_id = u.id join iam.units un on un.key = 'edr_freight_app' join iam.positions p on p.key = v.position_key and p.unit_id = un.id where not exists ( select 1 from iam.employee_positions ep where ep.employee_id = e.id and ep.position_id = p.id ); -- Backfill for rows created before start_date was included above. update iam.employee_positions set start_date = now() - interval '1 day' where start_date is null;