Skip to content

Commit ec8126e

Browse files
jhfclaude
andcommitted
fix: Update stale percentage references and use realistic test types
- doc/DOMAIN-MODELS.md: Replace 3 stale >=50% references with primary_influencer_only terminology - Tests 117/118/120: Use parent_company (TRUE, structurally 1:1) and co_ownership (FALSE, structurally 1:N) instead of misleading ownership/control which are both forms of influence - Test 119: Use real BRREG codes HFOR (TRUE) and DTPR (FALSE) to demonstrate the roller data flow with mixed types - Test 119: Now shows PG formation (Nordic→PG0001 via HFOR) alongside non-formation (Baltic via DTPR) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 8394fce commit ec8126e

10 files changed

+316
-274
lines changed

doc/DOMAIN-MODELS.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ STATBUS organizes data into distinct domains based on what we **observe** versus
2424
### Relationships
2525

2626
- **Legal Unit → Enterprise**: Every LU belongs to exactly one EN (always)
27-
- **Legal Relationship → Power Group**: Each controlling relationship (≥50%) belongs to a PG
27+
- **Legal Relationship → Power Group**: Each `primary_influencer_only` relationship belongs to a PG
2828
- **Legal Relationship → Legal Unit**: Tracks ownership/control between LUs (`influencing_id` owns/controls `influenced_id`)
2929
- **Establishment → Legal Unit**: Every ES belongs to exactly one LU
3030

@@ -36,8 +36,9 @@ Note: Power group membership of a Legal Unit is derived through `legal_relations
3636
- `legal_unit` - A legally registered entity (company, organization)
3737
- `legal_relationship` - Ownership/control relationship between two legal units
3838
- `influencing_id``influenced_id` (influencer owns/controls influenced)
39-
- `percentage` - ownership/control percentage (≥50% = controlling interest)
40-
- `power_group_id` - assigned by worker when relationship forms a controlling cluster
39+
- `percentage` - ownership/control percentage (optional, informational)
40+
- `primary_influencer_only` - denormalized from `legal_rel_type`; TRUE types form power groups
41+
- `power_group_id` - assigned by worker when relationship forms a primary-influencer cluster
4142

4243
**Physical Domain** (observed, temporal):
4344
- `establishment` - A physical location where economic activity occurs
@@ -46,7 +47,7 @@ Note: Power group membership of a Legal Unit is derived through `legal_relations
4647
- `enterprise` - The smallest combination of legal units that is an organizational unit producing goods or services
4748

4849
**Political Domain** (derived, non-temporal):
49-
- `power_group` - A hierarchy of legal units connected by controlling ownership (≥50%)
50+
- `power_group` - A hierarchy of legal units connected by `primary_influencer_only` relationships
5051
- Power groups are **TIMELESS** - once created, they exist forever as a registry entry
5152
- Active status is **derived** at query time from `legal_relationship.valid_range`
5253
- The `power_group_id` lives on `legal_relationship`, not `legal_unit`

test/data/roller_sample.csv

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
valid_from,valid_to,influencing_tax_ident,influenced_tax_ident,rel_type_code,percentage
2-
2020-01-01,infinity,100000001,100000002,control,100
3-
2020-01-01,infinity,100000001,100000003,control,100
4-
2020-01-01,infinity,100000002,100000004,control,100
5-
2020-01-01,infinity,100000002,100000005,control,100
6-
2020-01-01,infinity,100000003,100000006,control,100
7-
2020-01-01,infinity,100000003,100000007,control,100
8-
2020-01-01,infinity,100000008,100000009,control,100
9-
2020-01-01,infinity,100000008,100000010,control,100
2+
2020-01-01,infinity,100000001,100000002,HFOR,100
3+
2020-01-01,infinity,100000001,100000003,HFOR,100
4+
2020-01-01,infinity,100000002,100000004,HFOR,100
5+
2020-01-01,infinity,100000002,100000005,HFOR,100
6+
2020-01-01,infinity,100000003,100000006,HFOR,100
7+
2020-01-01,infinity,100000003,100000007,HFOR,100
8+
2020-01-01,infinity,100000008,100000009,DTPR,100
9+
2020-01-01,infinity,100000008,100000010,DTPR,100

test/expected/117_power_group_fundamentals.out

Lines changed: 58 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -35,25 +35,29 @@ DO UPDATE SET
3535
\copy public.legal_form_custom_only FROM 'samples/norway/legal_form/legal_form_norway.csv' WITH (FORMAT csv, DELIMITER ',', QUOTE '"', HEADER true);
3636
\i samples/norway/data_source/data_source_norway.sql
3737
\copy public.data_source_custom (code, name) FROM 'samples/norway/data_source/data_source_norway.csv' WITH (FORMAT csv, DELIMITER ',', QUOTE '"', HEADER true);
38-
-- Load seed data for legal_rel_type if not present
38+
-- Seed test relationship types that clearly demonstrate primary_influencer_only semantics
39+
-- parent_company: structurally 1:1 (a subsidiary has at most one parent) → TRUE
40+
-- co_ownership: structurally 1:N (multiple co-owners per entity) → FALSE
3941
INSERT INTO public.legal_rel_type (code, name, description, primary_influencer_only, enabled, custom)
40-
SELECT 'ownership', 'Ownership', 'Direct share ownership percentage', TRUE, true, false
41-
WHERE NOT EXISTS (SELECT 1 FROM public.legal_rel_type WHERE code = 'ownership');
42+
SELECT 'parent_company', 'Parent Company', 'Parent-subsidiary relationship (structurally 1:1 per subsidiary)', TRUE, true, false
43+
WHERE NOT EXISTS (SELECT 1 FROM public.legal_rel_type WHERE code = 'parent_company');
4244
INSERT INTO public.legal_rel_type (code, name, description, primary_influencer_only, enabled, custom)
43-
SELECT 'control', 'Control', 'Controlling interest (may differ from ownership via voting rights or agreements)', FALSE, true, false
44-
WHERE NOT EXISTS (SELECT 1 FROM public.legal_rel_type WHERE code = 'control');
45+
SELECT 'co_ownership', 'Co-ownership', 'Shared ownership (multiple co-owners per entity)', FALSE, true, false
46+
WHERE NOT EXISTS (SELECT 1 FROM public.legal_rel_type WHERE code = 'co_ownership');
4547
-- ============================================================================
4648
\echo "=== Section 1: Verify Schema Structure ==="
4749
"=== Section 1: Verify Schema Structure ==="
4850
-- ============================================================================
4951
\echo "Check legal_rel_type table exists with seed data"
5052
"Check legal_rel_type table exists with seed data"
5153
SELECT code, name, description, primary_influencer_only FROM public.legal_rel_type ORDER BY code;
52-
code | name | description | primary_influencer_only
53-
-----------+-----------+----------------------------------------------------------------------------------+-------------------------
54-
control | Control | Controlling interest (may differ from ownership via voting rights or agreements) | f
55-
ownership | Ownership | Direct share ownership percentage | t
56-
(2 rows)
54+
code | name | description | primary_influencer_only
55+
----------------+----------------+----------------------------------------------------------------------------------+-------------------------
56+
control | Control | Controlling interest (may differ from ownership via voting rights or agreements) | f
57+
co_ownership | Co-ownership | Shared ownership (multiple co-owners per entity) | f
58+
ownership | Ownership | Direct share ownership percentage | t
59+
parent_company | Parent Company | Parent-subsidiary relationship (structurally 1:1 per subsidiary) | t
60+
(4 rows)
5761

5862
\echo "Check power_group_type table exists (renamed from enterprise_group_type)"
5963
"Check power_group_type table exists (renamed from enterprise_group_type)"
@@ -257,20 +261,22 @@ ORDER BY name;
257261
(5 rows)
258262

259263
-- ============================================================================
260-
\echo "=== Section 3: Create Ownership Relationships ==="
261-
"=== Section 3: Create Ownership Relationships ==="
264+
\echo "=== Section 3: Create Parent-Company Relationships ==="
265+
"=== Section 3: Create Parent-Company Relationships ==="
262266
-- ============================================================================
263267
\echo "Get relationship type codes"
264268
"Get relationship type codes"
265269
SELECT code, name FROM public.legal_rel_type ORDER BY code;
266-
code | name
267-
-----------+-----------
268-
control | Control
269-
ownership | Ownership
270-
(2 rows)
270+
code | name
271+
----------------+----------------
272+
control | Control
273+
co_ownership | Co-ownership
274+
ownership | Ownership
275+
parent_company | Parent Company
276+
(4 rows)
271277

272-
\echo "Create ownership: Alpha Holdings owns 60% of Beta Manufacturing"
273-
"Create ownership: Alpha Holdings owns 60% of Beta Manufacturing"
278+
\echo "Create parent_company: Alpha Holdings is parent of Beta Manufacturing (60%)"
279+
"Create parent_company: Alpha Holdings is parent of Beta Manufacturing (60%)"
274280
INSERT INTO public.legal_relationship (
275281
valid_from,
276282
influencing_id,
@@ -284,12 +290,12 @@ SELECT
284290
'2020-01-01'::date,
285291
(SELECT id FROM public.legal_unit WHERE name = 'Alpha Holdings Corp' LIMIT 1),
286292
(SELECT id FROM public.legal_unit WHERE name = 'Beta Manufacturing Ltd' LIMIT 1),
287-
(SELECT id FROM public.legal_rel_type WHERE code = 'ownership'),
293+
(SELECT id FROM public.legal_rel_type WHERE code = 'parent_company'),
288294
60.00,
289295
(SELECT id FROM auth.user LIMIT 1),
290-
'Alpha owns 60% of Beta';
291-
\echo "Create ownership: Alpha Holdings owns 51% of Gamma Services"
292-
"Create ownership: Alpha Holdings owns 51% of Gamma Services"
296+
'Alpha is parent company of Beta';
297+
\echo "Create parent_company: Alpha Holdings is parent of Gamma Services (51%)"
298+
"Create parent_company: Alpha Holdings is parent of Gamma Services (51%)"
293299
INSERT INTO public.legal_relationship (
294300
valid_from,
295301
influencing_id,
@@ -303,12 +309,12 @@ SELECT
303309
'2020-01-01'::date,
304310
(SELECT id FROM public.legal_unit WHERE name = 'Alpha Holdings Corp' LIMIT 1),
305311
(SELECT id FROM public.legal_unit WHERE name = 'Gamma Services Inc' LIMIT 1),
306-
(SELECT id FROM public.legal_rel_type WHERE code = 'ownership'),
312+
(SELECT id FROM public.legal_rel_type WHERE code = 'parent_company'),
307313
51.00,
308314
(SELECT id FROM auth.user LIMIT 1),
309-
'Alpha owns 51% of Gamma';
310-
\echo "Create ownership: Beta Manufacturing owns 75% of Delta Components"
311-
"Create ownership: Beta Manufacturing owns 75% of Delta Components"
315+
'Alpha is parent company of Gamma';
316+
\echo "Create parent_company: Beta Manufacturing is parent of Delta Components (75%)"
317+
"Create parent_company: Beta Manufacturing is parent of Delta Components (75%)"
312318
INSERT INTO public.legal_relationship (
313319
valid_from,
314320
influencing_id,
@@ -322,12 +328,12 @@ SELECT
322328
'2020-01-01'::date,
323329
(SELECT id FROM public.legal_unit WHERE name = 'Beta Manufacturing Ltd' LIMIT 1),
324330
(SELECT id FROM public.legal_unit WHERE name = 'Delta Components GmbH' LIMIT 1),
325-
(SELECT id FROM public.legal_rel_type WHERE code = 'ownership'),
331+
(SELECT id FROM public.legal_rel_type WHERE code = 'parent_company'),
326332
75.00,
327333
(SELECT id FROM auth.user LIMIT 1),
328-
'Beta owns 75% of Delta';
329-
\echo "Verify ownership relationships created"
330-
"Verify ownership relationships created"
334+
'Beta is parent company of Delta';
335+
\echo "Verify parent-company relationships created"
336+
"Verify parent-company relationships created"
331337
SELECT
332338
influencer.name AS influencing_name,
333339
influenced.name AS influenced_name,
@@ -339,21 +345,21 @@ JOIN public.legal_unit AS influencer ON lr.influencing_id = influencer.id
339345
JOIN public.legal_unit AS influenced ON lr.influenced_id = influenced.id
340346
JOIN public.legal_rel_type AS rt ON lr.type_id = rt.id
341347
ORDER BY influencer.name, influenced.name;
342-
influencing_name | influenced_name | relationship | percentage | valid_from
343-
------------------------+------------------------+--------------+------------+------------
344-
Alpha Holdings Corp | Beta Manufacturing Ltd | ownership | 60.00 | 2020-01-01
345-
Alpha Holdings Corp | Gamma Services Inc | ownership | 51.00 | 2020-01-01
346-
Beta Manufacturing Ltd | Delta Components GmbH | ownership | 75.00 | 2020-01-01
348+
influencing_name | influenced_name | relationship | percentage | valid_from
349+
------------------------+------------------------+----------------+------------+------------
350+
Alpha Holdings Corp | Beta Manufacturing Ltd | parent_company | 60.00 | 2020-01-01
351+
Alpha Holdings Corp | Gamma Services Inc | parent_company | 51.00 | 2020-01-01
352+
Beta Manufacturing Ltd | Delta Components GmbH | parent_company | 75.00 | 2020-01-01
347353
(3 rows)
348354

349355
-- ============================================================================
350356
\echo "=== Section 4: Test Cycle Prevention ==="
351357
"=== Section 4: Test Cycle Prevention ==="
352358
-- ============================================================================
353-
\echo "Attempt to create circular ownership (should fail)"
354-
"Attempt to create circular ownership (should fail)"
355-
\echo "Trying: Delta owns Alpha (which would create Alpha -> Beta -> Delta -> Alpha cycle)"
356-
"Trying: Delta owns Alpha (which would create Alpha -> Beta -> Delta -> Alpha cycle)"
359+
\echo "Attempt to create circular parent_company (should fail)"
360+
"Attempt to create circular parent_company (should fail)"
361+
\echo "Trying: Delta is parent of Alpha (which would create Alpha -> Beta -> Delta -> Alpha cycle)"
362+
"Trying: Delta is parent of Alpha (which would create Alpha -> Beta -> Delta -> Alpha cycle)"
357363
DO $$
358364
BEGIN
359365
INSERT INTO public.legal_relationship (
@@ -369,10 +375,10 @@ BEGIN
369375
'2020-01-01'::date,
370376
(SELECT id FROM public.legal_unit WHERE name = 'Delta Components GmbH' LIMIT 1),
371377
(SELECT id FROM public.legal_unit WHERE name = 'Alpha Holdings Corp' LIMIT 1),
372-
(SELECT id FROM public.legal_rel_type WHERE code = 'ownership'),
378+
(SELECT id FROM public.legal_rel_type WHERE code = 'parent_company'),
373379
30.00,
374380
(SELECT id FROM auth.user LIMIT 1),
375-
'Delta owns Alpha - SHOULD FAIL';
381+
'Delta is parent of Alpha - SHOULD FAIL';
376382

377383
RAISE EXCEPTION 'TEST FAILURE: Circular ownership was allowed - cycle prevention did not work!';
378384
EXCEPTION
@@ -422,7 +428,7 @@ BEGIN
422428
'2020-01-01'::date,
423429
_alpha_id,
424430
_alpha_id, -- Same as influencing - should fail
425-
(SELECT id FROM public.legal_rel_type WHERE code = 'ownership'),
431+
(SELECT id FROM public.legal_rel_type WHERE code = 'parent_company'),
426432
100.00,
427433
(SELECT id FROM auth.user LIMIT 1),
428434
'Self-reference - SHOULD FAIL'
@@ -540,8 +546,8 @@ ORDER BY influencer.name, influenced.name;
540546
\echo "=== Section 8: Test Temporal Aspects ==="
541547
"=== Section 8: Test Temporal Aspects ==="
542548
-- ============================================================================
543-
\echo "Add a new ownership relationship starting later (2023)"
544-
"Add a new ownership relationship starting later (2023)"
549+
\echo "Add a new parent_company relationship starting later (2023)"
550+
"Add a new parent_company relationship starting later (2023)"
545551
INSERT INTO public.legal_relationship (
546552
valid_from,
547553
influencing_id,
@@ -556,13 +562,13 @@ SELECT
556562
'2023-01-01'::date,
557563
(SELECT id FROM public.legal_unit WHERE name = 'Alpha Holdings Corp' LIMIT 1),
558564
(SELECT id FROM public.legal_unit WHERE name = 'Epsilon Independent LLC' LIMIT 1),
559-
(SELECT id FROM public.legal_rel_type WHERE code = 'ownership'),
565+
(SELECT id FROM public.legal_rel_type WHERE code = 'parent_company'),
560566
55.00,
561567
(SELECT id FROM public.legal_reorg_type WHERE code = 'acq' LIMIT 1),
562568
(SELECT id FROM auth.user LIMIT 1),
563-
'Alpha acquires Epsilon in 2023';
564-
\echo "Verify temporal ownership - before acquisition (2022)"
565-
"Verify temporal ownership - before acquisition (2022)"
569+
'Alpha becomes parent company of Epsilon in 2023';
570+
\echo "Verify temporal relationships - before acquisition (2022)"
571+
"Verify temporal relationships - before acquisition (2022)"
566572
SELECT
567573
influencer.name AS influencing_name,
568574
influenced.name AS influenced_name,
@@ -581,8 +587,8 @@ ORDER BY influencer.name, influenced.name;
581587
Beta Manufacturing Ltd | Delta Components GmbH | 75.00 | 2020-01-01 | infinity
582588
(3 rows)
583589

584-
\echo "Verify temporal ownership - after acquisition (2024)"
585-
"Verify temporal ownership - after acquisition (2024)"
590+
\echo "Verify temporal relationships - after acquisition (2024)"
591+
"Verify temporal relationships - after acquisition (2024)"
586592
SELECT
587593
influencer.name AS influencing_name,
588594
influenced.name AS influenced_name,
@@ -617,7 +623,7 @@ GROUP BY rt.code
617623
ORDER BY rt.code;
618624
relationship_type | count
619625
-------------------+-------
620-
ownership | 4
626+
parent_company | 4
621627
(1 row)
622628

623629
\echo "Relationships with power_group assignment"

0 commit comments

Comments
 (0)