chore(seed): bake live test connections into init.sql + helpdesk migration
Fresh installs now come up with working dev test connections for Microsoft SSO and Business Central without manual configuration: - init.sql appends the live breadcrumb + icoreon tenants (idempotent by uuid), Felix as a 6th user with all five roles, the live departments, plus tenant_auth_microsoft (SSO enabled for breadcrumb), tenant_auth_ldap stubs, and the global Microsoft shared-app credentials. The MusterMandant demo seed is preserved as tenant 1. - A new helpdesk migration 011 seeds the per-tenant BC connection rows in helpdesk_tenant_settings and the helpdesk.bc_* fallback settings — module-owned data stays in module migrations. - .env.example sets APP_CRYPTO_KEY so the AES-256-GCM blobs in the seed (Microsoft client secret, BC basic auth passwords) actually decrypt out-of-the-box. Verified by decrypting all four blobs end-to-end through Crypto::decryptString. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
201
db/init/init.sql
201
db/init/init.sql
@@ -1749,3 +1749,204 @@ CROSS JOIN (
|
||||
) n
|
||||
WHERE u.email = 'demo@user.com'
|
||||
AND NOT EXISTS (SELECT 1 FROM user_notifications un WHERE un.recipient_user_id = u.id);
|
||||
|
||||
-- =============================================
|
||||
-- Seed: Live test data — breadcrumb + icoreon tenants
|
||||
-- ---------------------------------------------
|
||||
-- Snapshot of the local dev DB so a fresh `docker compose up` immediately
|
||||
-- has working test connections for Microsoft SSO (login) and Business
|
||||
-- Central (helpdesk). Encrypted secrets below are AES-256-GCM blobs
|
||||
-- produced with APP_CRYPTO_KEY=9792a9ce0def59c034a651f2f6f26f3dcda2f78c1e3513e67be4da06afc24680
|
||||
-- (set in .env.example). Decryption fails if the key differs.
|
||||
-- All inserts are idempotent: re-running init.sql is a no-op.
|
||||
-- =============================================
|
||||
|
||||
-- ─── Live tenant 1: breadcrumb mediasolutions GmbH ───
|
||||
INSERT INTO `tenants` (
|
||||
`uuid`, `description`, `address`, `postal_code`, `city`, `country`, `region`,
|
||||
`vat_id`, `tax_number`, `phone`, `fax`, `email`, `support_email`, `support_phone`,
|
||||
`billing_email`, `website`, `privacy_url`, `imprint_url`,
|
||||
`primary_color`, `default_theme`, `allow_user_theme`, `status`, `created`
|
||||
)
|
||||
SELECT
|
||||
'57349d01-262e-11f1-8ada-dab0b621b876', 'breadcrumb mediasolutions GmbH',
|
||||
'Kressenstein 26', '10115', 'Berlin', 'Deutschland', 'Berlin',
|
||||
'DE123456789', '12/345/67890', '+49 30 12345670', '+49 30 12345679',
|
||||
'info@mustermandant.de', 'support@mustermandant.de', '+49 30 12345671',
|
||||
'billing@mustermandant.de', 'https://www.mustermandant.de',
|
||||
'https://www.mustermandant.de/datenschutz', 'https://www.mustermandant.de/impressum',
|
||||
'#218687', 'dark', 1, 'active', NOW()
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM tenants WHERE uuid = '57349d01-262e-11f1-8ada-dab0b621b876'
|
||||
);
|
||||
|
||||
-- ─── Live tenant 2: icoreon GmbH ───
|
||||
INSERT INTO `tenants` (
|
||||
`uuid`, `description`, `primary_color`, `status`, `status_changed_at`, `created`
|
||||
)
|
||||
SELECT
|
||||
'ab99e81c-471a-4db0-aa24-c198a5c58557', 'icoreon GmbH',
|
||||
'#ff8c13', 'active', NOW(), NOW()
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM tenants WHERE uuid = 'ab99e81c-471a-4db0-aa24-c198a5c58557'
|
||||
);
|
||||
|
||||
-- ─── Live departments (breadcrumb tenant) ───
|
||||
INSERT INTO `departments` (`uuid`, `description`, `tenant_id`, `code`, `active`, `created`)
|
||||
SELECT '5734c4f6-262e-11f1-8ada-dab0b621b876', 'Customer Care', t.id, 'CUSTOMERCARE', 1, NOW()
|
||||
FROM tenants t
|
||||
WHERE t.uuid = '57349d01-262e-11f1-8ada-dab0b621b876'
|
||||
AND NOT EXISTS (SELECT 1 FROM departments WHERE uuid = '5734c4f6-262e-11f1-8ada-dab0b621b876');
|
||||
|
||||
INSERT INTO `departments` (`uuid`, `description`, `tenant_id`, `code`, `active`, `created`)
|
||||
SELECT '5734d6cd-262e-11f1-8ada-dab0b621b876', 'Customer Success Management', t.id, 'CSM', 1, NOW()
|
||||
FROM tenants t
|
||||
WHERE t.uuid = '57349d01-262e-11f1-8ada-dab0b621b876'
|
||||
AND NOT EXISTS (SELECT 1 FROM departments WHERE uuid = '5734d6cd-262e-11f1-8ada-dab0b621b876');
|
||||
|
||||
INSERT INTO `departments` (`uuid`, `description`, `tenant_id`, `code`, `active`, `created`)
|
||||
SELECT 'e2fd85de-2009-4ba8-8cd2-bbe04ae17211', 'Customizing', t.id, 'CUSTI', 1, NOW()
|
||||
FROM tenants t
|
||||
WHERE t.uuid = '57349d01-262e-11f1-8ada-dab0b621b876'
|
||||
AND NOT EXISTS (SELECT 1 FROM departments WHERE uuid = 'e2fd85de-2009-4ba8-8cd2-bbe04ae17211');
|
||||
|
||||
INSERT INTO `departments` (`uuid`, `description`, `tenant_id`, `code`, `active`, `created`)
|
||||
SELECT '074fa03d-e74e-4073-879c-9ac8e8abe0ae', 'Management', t.id, 'MANAGEMENT', 1, NOW()
|
||||
FROM tenants t
|
||||
WHERE t.uuid = '57349d01-262e-11f1-8ada-dab0b621b876'
|
||||
AND NOT EXISTS (SELECT 1 FROM departments WHERE uuid = '074fa03d-e74e-4073-879c-9ac8e8abe0ae');
|
||||
|
||||
INSERT INTO `departments` (`uuid`, `description`, `tenant_id`, `code`, `active`, `created`)
|
||||
SELECT 'caf24a7d-e210-4b1c-830c-54734c2c879f', 'Marketing', t.id, 'MARKETING', 1, NOW()
|
||||
FROM tenants t
|
||||
WHERE t.uuid = '57349d01-262e-11f1-8ada-dab0b621b876'
|
||||
AND NOT EXISTS (SELECT 1 FROM departments WHERE uuid = 'caf24a7d-e210-4b1c-830c-54734c2c879f');
|
||||
|
||||
INSERT INTO `departments` (`uuid`, `description`, `tenant_id`, `code`, `active`, `created`)
|
||||
SELECT 'aaedbb3f-2cea-4f22-9bb2-873d2db28a14', 'Produktentwicklung', t.id, 'PRODUKTENT', 1, NOW()
|
||||
FROM tenants t
|
||||
WHERE t.uuid = '57349d01-262e-11f1-8ada-dab0b621b876'
|
||||
AND NOT EXISTS (SELECT 1 FROM departments WHERE uuid = 'aaedbb3f-2cea-4f22-9bb2-873d2db28a14');
|
||||
|
||||
INSERT INTO `departments` (`uuid`, `description`, `tenant_id`, `code`, `active`, `created`)
|
||||
SELECT 'c84ef0ab-16df-4b0f-91a8-5787c661ad21', 'Projects', t.id, 'PROJECTS', 1, NOW()
|
||||
FROM tenants t
|
||||
WHERE t.uuid = '57349d01-262e-11f1-8ada-dab0b621b876'
|
||||
AND NOT EXISTS (SELECT 1 FROM departments WHERE uuid = 'c84ef0ab-16df-4b0f-91a8-5787c661ad21');
|
||||
|
||||
INSERT INTO `departments` (`uuid`, `description`, `tenant_id`, `code`, `active`, `created`)
|
||||
SELECT '01845fdb-d21b-43e2-a483-7f8318a096f8', 'Verwaltung', t.id, 'VERWALTUNG', 1, NOW()
|
||||
FROM tenants t
|
||||
WHERE t.uuid = '57349d01-262e-11f1-8ada-dab0b621b876'
|
||||
AND NOT EXISTS (SELECT 1 FROM departments WHERE uuid = '01845fdb-d21b-43e2-a483-7f8318a096f8');
|
||||
|
||||
-- ─── Live user: Felix Schneider ───
|
||||
INSERT INTO `users` (
|
||||
`uuid`, `first_name`, `last_name`, `display_name`, `email`,
|
||||
`job_title`, `phone`, `email_verified_at`, `last_login_provider`,
|
||||
`password`, `locale`, `theme`, `created`, `active`, `authz_version`, `active_changed_at`
|
||||
)
|
||||
SELECT
|
||||
'bf88fbcf-b25d-4799-bd52-653d7be5890f',
|
||||
'Felix', 'Schneider', 'Felix Schneider', 'fs@breadcrumb-solutions.de',
|
||||
'Software Product Developer', '09221 80246-73',
|
||||
NOW(), 'local',
|
||||
'$2y$12$EPRwI4HoS.uzyTMlCTyHFeOFcWzcUWdqn7jDCo7syXZdJCyYDs7aO',
|
||||
'de', 'dark', NOW(), 1, 1, NOW()
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM users WHERE uuid = 'bf88fbcf-b25d-4799-bd52-653d7be5890f'
|
||||
);
|
||||
|
||||
UPDATE `users`
|
||||
SET `primary_tenant_id` = (SELECT id FROM tenants WHERE uuid = '57349d01-262e-11f1-8ada-dab0b621b876'),
|
||||
`current_tenant_id` = (SELECT id FROM tenants WHERE uuid = '57349d01-262e-11f1-8ada-dab0b621b876')
|
||||
WHERE uuid = 'bf88fbcf-b25d-4799-bd52-653d7be5890f'
|
||||
AND `primary_tenant_id` IS NULL;
|
||||
|
||||
-- ─── Felix → tenants (breadcrumb + icoreon) ───
|
||||
INSERT IGNORE INTO `user_tenants` (`user_id`, `tenant_id`, `created`)
|
||||
SELECT u.id, t.id, NOW()
|
||||
FROM users u
|
||||
CROSS JOIN tenants t
|
||||
WHERE u.uuid = 'bf88fbcf-b25d-4799-bd52-653d7be5890f'
|
||||
AND t.uuid IN (
|
||||
'57349d01-262e-11f1-8ada-dab0b621b876',
|
||||
'ab99e81c-471a-4db0-aa24-c198a5c58557'
|
||||
);
|
||||
|
||||
-- ─── Felix → all roles (admin/user/manager/auditor/support) ───
|
||||
INSERT IGNORE INTO `user_roles` (`user_id`, `role_id`, `created`)
|
||||
SELECT u.id, r.id, NOW()
|
||||
FROM users u
|
||||
CROSS JOIN roles r
|
||||
WHERE u.uuid = 'bf88fbcf-b25d-4799-bd52-653d7be5890f'
|
||||
AND r.code IN ('ADMIN', 'USER', 'MANAGER', 'AUDITOR', 'SUPPORT');
|
||||
|
||||
-- ─── Felix → Customer Care department ───
|
||||
INSERT IGNORE INTO `user_departments` (`user_id`, `department_id`, `created`)
|
||||
SELECT u.id, d.id, NOW()
|
||||
FROM users u
|
||||
CROSS JOIN departments d
|
||||
WHERE u.uuid = 'bf88fbcf-b25d-4799-bd52-653d7be5890f'
|
||||
AND d.uuid = '5734c4f6-262e-11f1-8ada-dab0b621b876';
|
||||
|
||||
-- ─── tenant_auth_microsoft (live SSO config) ───
|
||||
INSERT INTO `tenant_auth_microsoft` (
|
||||
`tenant_id`, `enabled`, `enforce_microsoft_login`, `sync_profile_on_login`,
|
||||
`sync_profile_fields`, `entra_tenant_id`, `allowed_domains`, `use_shared_app`, `created`
|
||||
)
|
||||
SELECT t.id, 1, 1, 1,
|
||||
'first_name,last_name,display_name,job_title,phone,mobile,avatar',
|
||||
'52e93e91-ea23-42ee-bbd9-77194dc9886b',
|
||||
'breadcrumb-solutions.de', 1, NOW()
|
||||
FROM tenants t
|
||||
WHERE t.uuid = '57349d01-262e-11f1-8ada-dab0b621b876'
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM tenant_auth_microsoft tm WHERE tm.tenant_id = t.id
|
||||
);
|
||||
|
||||
INSERT INTO `tenant_auth_microsoft` (
|
||||
`tenant_id`, `enabled`, `enforce_microsoft_login`, `sync_profile_on_login`, `use_shared_app`, `created`
|
||||
)
|
||||
SELECT t.id, 0, 0, 0, 0, NOW()
|
||||
FROM tenants t
|
||||
WHERE t.uuid = 'ab99e81c-471a-4db0-aa24-c198a5c58557'
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM tenant_auth_microsoft tm WHERE tm.tenant_id = t.id
|
||||
);
|
||||
|
||||
-- ─── tenant_auth_ldap (disabled stubs for live tenants) ───
|
||||
INSERT INTO `tenant_auth_ldap` (
|
||||
`tenant_id`, `enabled`, `enforce_ldap_login`, `host`, `port`, `encryption_mode`,
|
||||
`verify_tls_certificate`, `base_dn`, `user_search_filter`, `user_search_scope`,
|
||||
`bind_method`, `unique_id_attribute`, `attribute_map`, `sync_profile_on_login`,
|
||||
`network_timeout`, `created`
|
||||
)
|
||||
SELECT t.id, 0, 0, '', 389, 'starttls', 0, '',
|
||||
'(&(objectClass=user)(sAMAccountName=%s))', 'sub', 'search_then_bind',
|
||||
'objectGUID',
|
||||
'{"first_name":"givenName","last_name":"sn","email":"mail","phone":"telephoneNumber","mobile":"mobile"}',
|
||||
0, 5, NOW()
|
||||
FROM tenants t
|
||||
WHERE t.uuid IN (
|
||||
'57349d01-262e-11f1-8ada-dab0b621b876',
|
||||
'ab99e81c-471a-4db0-aa24-c198a5c58557'
|
||||
)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM tenant_auth_ldap tl WHERE tl.tenant_id = t.id
|
||||
);
|
||||
|
||||
-- ─── Global settings (live overrides + Microsoft SSO secrets) ───
|
||||
-- Helpdesk-specific settings (helpdesk.bc_*) and helpdesk_tenant_settings rows
|
||||
-- live in modules/helpdesk/migrations/011_seed_test_tenant_connections.sql
|
||||
-- so they only seed when the helpdesk module is enabled.
|
||||
INSERT INTO `settings` (`key`, `value`, `description`)
|
||||
VALUES
|
||||
('app_primary_color', '#105433', 'setting.app_primary_color'),
|
||||
('app_theme', 'light', 'setting.app_theme'),
|
||||
('app_theme_user', '1', 'setting.app_theme_user'),
|
||||
('microsoft_authority', 'https://login.microsoftonline.com/common/v2.0', 'setting.microsoft_authority'),
|
||||
('microsoft_shared_client_id', '995297b2-e0f7-4cec-abc5-1e6f9704272f', 'setting.microsoft_shared_client_id'),
|
||||
('microsoft_shared_client_secret_enc', 'eyJ2IjoxLCJpdiI6IjloU0ZRb3FWVHZxMUlubVciLCJ0YWciOiJSYzZVbVlCNzZzMi1nOFVZVFYteXd3IiwiY3QiOiJaV1hjQUdGRVk1YjZJRjhZRjlfWlBKeUg5c2JkbjBVOHlSemcwYUc4S01DcFgwa2xnd3pvVEEifQ==', 'setting.microsoft_shared_client_secret_enc')
|
||||
ON DUPLICATE KEY UPDATE
|
||||
`value` = VALUES(`value`);
|
||||
|
||||
Reference in New Issue
Block a user