Standard and Test Data

1. Overview

The Events and Membership Management System uses Liquibase for database schema management and data seeding. Seed data is categorised into two types:

Standard Data

Master data loaded for all instances (production and development). This includes reference data like countries, disciplines, and the organisational hierarchy.

Test Data

Development-only data loaded via the Liquibase faker context. This includes sample persons, memberships, events, and process definitions used for testing and development.

2. Data Locations

Repository Standard Data Test Data

event-database

src/main/resources/liquibase/data/

src/main/resources/liquibase/fake-data/

registration-portal

src/main/resources/config/liquibase/data/

src/main/resources/config/liquibase/fake-data/

3. Standard Data (event-database)

Standard data provides foundational master data required for system operation.

3.1. Countries

File: data/country.csv

Complete ISO 3166-1 alpha-2 country list with 250 countries.

Name Code

South Africa

ZA

United States

US

United Kingdom

GB

…​

(250 total)

3.2. Disciplines

File: data/discipline.csv

Sporting disciplines managed by responsible organisations.

ID Name Responsible Organisation

1

Road Cycling

1 (UCI)

2

Mountain Bike

1 (UCI)

3

Track Cycling

1 (UCI)

3.3. Organisations

File: data/organisation.csv

Standard organisational hierarchy for cycling governance. Uses semicolon delimiter.

ID Name Parent ID

1

UCI

NULL

2

Cycling South Africa

1

3

Western Cape Cycling Association

2

4

Western Province Cycling Association

3

5

Winelands

3

6

West Coast

3

7

Eden

3

org-hierarchy

3.4. Race Types

File: data/race_type.csv

Standard race type classifications linked to disciplines.

ID Name Discipline ID

Road Cycling (Discipline 1)

1

Road Race

1

2

Time Trial

1

3

Criterium

1

Track Cycling (Discipline 3)

7

Individual Pursuit

3

8

Match Sprint

3

9

Time Trial

3

10

1500m

3

11

Points Race

3

12

Team Pursuit

3

13

Scratch Race

3

14

Team Sprint

3

15

Elimination

3

16

Keirin

3

17

Madison

3

18

Omnium

3

4. Test Data (event-database/fake-data)

Test data provides sample records for development and testing scenarios.

4.1. Test Organisations

File: fake-data/organisation.csv

Additional test organisations beyond the standard hierarchy.

ID Name Parent ID

8

Helderberg Nature Reserve

NULL

9

Western Cape Schools Cycling

NULL

10

Beta Club

NULL

4.2. Registration Systems

File: fake-data/registration_system.csv

External systems that integrate with the platform for user authentication and data synchronisation.

ID Name Type Organisation

1

Wordpress1

WP2

4 (Western Province Cycling Association)

2

WCSC Website

WP2

9 (Western Cape Schools Cycling)

3

RaceResult

RR

1 (UCI)

4

BlackBox

BB

1 (UCI)

5

RunSignup

RS

1 (UCI)

6

EntryNinja

EN

1 (UCI)

7

HNR Website

ME1

8 (Helderberg Nature Reserve)

8

Myriadv2

ME2

1 (UCI)

9

Manual

MAN

1 (UCI)

10

Custom

CUS

1 (UCI)

Registration System Types:

  • WP2 - WordPress v2 integration

  • ME1 / ME2 - Myriad Events v1/v2

  • RR - RaceResult integration

  • BB - BlackBox timing

  • RS - RunSignup

  • EN - EntryNinja

  • MAN - Manual entry

  • CUS - Custom integration

4.3. Person Data

Person data is currently stored in legacy WordPress tables (wp_users and wp_usermeta). The wp_usermeta table extends person records with additional attributes. This schema will be migrated to a dedicated Person entity.

Files:

  • fake-data/wp_users.csv - Core person records

  • fake-data/wp_usermeta.csv - Person attributes (first_name, last_name, date_of_birth, gender, id_number, id_type, id_country)

ID Name Email Gender Date of Birth

1

Albert Allison

[email protected]

M

1999-06-10

2

Bertha Benson

[email protected]

F

1976-12-08

3

Charlie Chesterton

[email protected]

M

1995-10-25

4

Danny Davids

[email protected]

M

1983-05-04

5

Eddie Edwards

[email protected]

M

1986-03-06

6

Freddie Foster

[email protected]

M

1986-05-04

7

Gail Geldenhuys

[email protected]

F

1979-09-26

8

Henry Harrison

[email protected]

M

1997-02-07

9

Isaac Ironborn

[email protected]

M

1979-07-22

10

Jack Jefferson

[email protected]

M

1996-08-12

11

Kate Kennedy

[email protected]

F

1985-03-15

12

Luke Lancaster

[email protected]

M

2012-07-20

13

Mia Mitchell

[email protected]

F

2010-11-05

14

Noah Nelson

[email protected]

M

2014-02-28

15

Olivia Owens

[email protected]

F

1988-09-12

4.3.1. Identity Documents

Each person has an identity document stored in wp_usermeta. Approximately 73% have South African ID numbers (NATIONAL), while 27% have passports.

Identity Types:

  • NATIONAL - South African ID Number (13 digits with Luhn checksum)

  • PASSPORT - Foreign passport number

SA ID Format: YYMMDDGSSS08C

  • YYMMDD - Date of birth (6 digits)

  • G - Gender digit (0-4 female, 5-9 male)

  • SSS - 3-digit sequence number

  • 0 - SA citizen indicator

  • 8 - Race indicator (deprecated, always 8)

  • C - Luhn checksum digit

ID Name Type Identity Number Country

South African ID Numbers (NATIONAL)

1

Albert Allison

NATIONAL

9906105001084

ZA

2

Bertha Benson

NATIONAL

7612080001088

ZA

3

Charlie Chesterton

NATIONAL

9510255002080

ZA

4

Danny Davids

NATIONAL

8305045003087

ZA

5

Eddie Edwards

NATIONAL

8603065004081

ZA

7

Gail Geldenhuys

NATIONAL

7909260002086

ZA

8

Henry Harrison

NATIONAL

9702075005086

ZA

9

Isaac Ironborn

NATIONAL

7907225006084

ZA

10

Jack Jefferson

NATIONAL

9608125007085

ZA

11

Kate Kennedy

NATIONAL

8503150003086

ZA

12

Luke Lancaster

NATIONAL

1207205008083

ZA

Passports

6

Freddie Foster

PASSPORT

GB000001

GB

13

Mia Mitchell

PASSPORT

US000001

US

14

Noah Nelson

PASSPORT

DE000001

DE

15

Olivia Owens

PASSPORT

AU000001

AU

SA ID numbers have valid Luhn checksums and can be used for validation testing. Passport numbers follow the pattern XX000001 where XX is the country code.

4.3.2. Age Calculation Reference

Based on reference date 2025-01-01:

ID Name Age Category

1

Albert Allison

25

Adult

2

Bertha Benson

48

Adult

3

Charlie Chesterton

29

Adult

4

Danny Davids

41

Adult

5

Eddie Edwards

38

Adult

6

Freddie Foster

38

Adult

7

Gail Geldenhuys

45

Adult

8

Henry Harrison

27

Adult

9

Isaac Ironborn

45

Adult

10

Jack Jefferson

28

Adult

11

Kate Kennedy

39

Adult

12

Luke Lancaster

12

Minor

13

Mia Mitchell

14

Minor

14

Noah Nelson

10

Minor

15

Olivia Owens

36

Adult

4.4. OrgUser Records

File: fake-data/org_user.csv

Links persons to organisation membership and user accounts.

4.4.1. Organisation 8 (Helderberg Nature Reserve)

ID Active Person ID User ID Organisation ID

1

true

1 (Albert)

1

8 (HNR)

2

true

2 (Bertha)

2

8

3

true

3 (Charlie)

3

8

4

true

4 (Danny)

4

8

5

true

5 (Eddie)

5

8

6

true

6 (Freddie)

6

8

7

true

7 (Gail)

7

8

8

true

8 (Henry)

8

8

9

true

9 (Isaac)

9

8

10

true

10 (Jack)

10

8

11

true

11 (Kate)

11

8

12

true

12 (Luke)

NULL

8

13

true

13 (Mia)

NULL

8

14

true

14 (Noah)

NULL

8

15

true

15 (Olivia)

15

8

Persons 12-14 (minors) have NULL user_id as they don’t have login accounts.

4.4.2. Organisation 4 (WPCA - Cycling)

ID Active Person ID User ID Organisation ID

20

true

3 (Charlie)

3

4 (WPCA)

21

true

4 (Danny)

4

4

22

true

5 (Eddie)

5

4

23

true

7 (Gail)

7

4

24

true

9 (Isaac)

9

4

25

true

10 (Jack)

10

4

26

true

15 (Olivia)

15

4

This demonstrates multi-organisation membership where persons can belong to both HNR and the cycling association.

4.4.3. External Authentication Hashes

For external authentication via /auth/external-login, a user hash is required. The hash is calculated as:

MD5(Base64Decode(secretKey) + userId)

Where secretKey is the configured value (default: c2VjcmV0c3RyaW5n which decodes to secretstring).

User ID Person Hash

1

Albert

6f7b1a88fb18965daef7e07bd17b3c8a

2

Bertha

c858f9565f2a9677e213de235a896fa1

3

Charlie

d6a0f7e0d17dde474623d6ca74dac912

4

Danny

e7cb51ec991528bf30e3e524afc7bc99

5

Eddie

0f7260624956f70cde2ee1f48a69b788

6

Freddie

6f0e3083e71415599ec95fcf67c2bc6d

7

Gail

8ee92b84eed7dab1215c33fcba777fa2

8

Henry

f1209019d2c117224c9717cccdb599ea

9

Isaac

a37785d533f182118dbd36a282aba9b4

10

Jack

f7be6e2763d88a9f30180dd4cc3f0611

11

Kate

84eb884c6cf8dedbbe45d0fd51d01482

15

Olivia

561c2f60fdb05ec83570934a477878aa

Users 12-14 (Luke, Mia, Noah) are minors without login accounts (NULL user_id) and therefore have no authentication hash.

4.5. LinkedPerson Records

File: fake-data/linked_person.csv

Defines relationships between persons for group registration scenarios.

ID Type Principal Linked Person

1

GENERAL

1 (Albert)

2 (Bertha)

2

GENERAL

1 (Albert)

3 (Charlie)

3

GENERAL

3 (Charlie)

4 (Danny)

4

GENERAL

3 (Charlie)

5 (Eddie)

5

NONE

3 (Charlie)

6 (Freddie)

6

NONE

3 (Charlie)

7 (Gail)

7

GUARDIAN

3 (Charlie)

8 (Henry)

8

GUARDIAN

3 (Charlie)

9 (Isaac)

9

NONE

1 (Albert)

10 (Jack)

10

GUARDIAN

9 (Isaac)

10 (Jack)

11

GENERAL

7 (Gail)

11 (Kate)

12

GUARDIAN

7 (Gail)

12 (Luke)

13

GUARDIAN

7 (Gail)

13 (Mia)

14

GUARDIAN

11 (Kate)

12 (Luke)

15

GUARDIAN

11 (Kate)

13 (Mia)

16

GUARDIAN

1 (Albert)

14 (Noah)

17

GENERAL

7 (Gail)

15 (Olivia)

18

NONE

9 (Isaac)

15 (Olivia)

19

NONE

7 (Gail)

10 (Jack)

20

GENERAL

15 (Olivia)

6 (Freddie)

Link Types:

  • GENERAL - Standard link for family or friends

  • GUARDIAN - Guardian/dependent relationship (for minors)

  • NONE - Link exists but no special permissions

4.5.1. Overlapping Relationships

Jack (Person 10) is intentionally linked to multiple principals to test overlapping scenarios:

  • Albert → Jack (NONE)

  • Isaac → Jack (GUARDIAN)

  • Gail → Jack (NONE)

Luke and Mia (Persons 12-13) demonstrate co-parenting with dual guardianship:

  • Gail → Luke/Mia (GUARDIAN)

  • Kate → Luke/Mia (GUARDIAN)

linked-persons

4.6. Membership Types

File: fake-data/membership_type.csv

ID Name Organisation ID

1

Alfa Club Membership

1

2

Beta Club Membership

2

3

Charlie Club Membership

3

4

Delta Club Membership

4

5

Echo Club Membership

5

6

Foxtrot Club Membership

6

7

Golf Club Membership

7

8

Hotel Club Membership

8

9

Road Cycling Membership

9

10

MTB Membership

9

11

Annual Membership

8 (HNR)

12

Early Riser Membership

8 (HNR)

4.7. Membership Periods

File: fake-data/membership_period.csv

ID Name Valid From Valid To Type ID Enrol Process Default Criteria

1

2018

2018-01-01

2018-12-31

1

1

2 (Adult)

2

2019

2019-01-01

2019-12-31

1

2

5 (Adult)

3

2020

2020-01-01

2020-12-31

1

3

8 (Adult)

4

2021

2020-09-01

2021-12-31

1

NULL

NULL

5

Lifetime

2018-01-01

NULL

2

NULL

NULL

6-9

2018-2021

Various

Various

2

NULL

NULL

10-16

2020

2020-01-01

2020-12-31

3-9

NULL

NULL

4.7.1. HNR Membership Periods (Financial Year April-March)

ID Name Valid From Valid To Type ID Enrol Process Default Criteria

Annual Membership (Type 11)

20

2023/24

2023-04-01

2024-03-31

11

NULL

NULL

21

2024/25

2024-04-01

2025-03-31

11

3

24 (Adult)

22

2025/26

2025-04-01

2026-03-31

11

3

28 (Adult)

Early Riser Membership (Type 12)

23

2023/24

2023-04-01

2024-03-31

12

NULL

NULL

24

2024/25

2024-04-01

2025-03-31

12

NULL

NULL

25

2025/26

2025-04-01

2026-03-31

12

NULL

NULL

Default Criteria Requirement: When a membership period has an enrol_process_id (i.e., uses a process-driven registration workflow), the default_criteria_id must be set. This criteria is used as a fallback when a person does not match any age/gender-based criteria during the membership registration process.

Periods without a process definition (direct registration) do not require a default criteria.

The enrol_process_id links membership periods to process definitions for registration workflows.

4.8. Membership Criteria

File: fake-data/membership_criteria.csv

Age-based membership tiers with associated products.

ID Name Min Age Max Age Period ID Product ID

1

Youth

NULL

17

1

7 (Adult Membership)

2

Adult

18

59

1

8 (Child Membership)

3

Senior

60

NULL

1

9 (Senior Membership)

4-6

Youth/Adult/Senior

Various

Various

2

7/8/9

7-9

Youth/Adult/Senior

Various

Various

3

7/8/9

10-12

Youth/Adult/Senior

Various

Various

4

7/8/9

13

All

NULL

NULL

5 (Lifetime)

NULL

4.8.1. HNR Membership Criteria

ID Name Min Age Max Age Period ID Product ID

Annual Membership 2023/24 (Period 20)

20

Adult

18

59

20

7 (Adult R250)

21

Child

NULL

17

20

8 (Child R50)

22

Senior

60

NULL

20

9 (Senior R150)

23

Family

NULL

NULL

20

11 (Family R600)

Annual Membership 2024/25 (Period 21)

24

Adult

18

59

21

7

25

Child

NULL

17

21

8

26

Senior

60

NULL

21

9

27

Family

NULL

NULL

21

11

Annual Membership 2025/26 (Period 22)

28

Adult

18

59

22

7

29

Child

NULL

17

22

8

30

Senior

60

NULL

22

9

31

Family

NULL

NULL

22

11

Early Riser Membership (Periods 23-25)

32

Default

NULL

NULL

23

12 (Early Riser R200)

33

Default

NULL

NULL

24

12

34

Default

NULL

NULL

25

12

4.9. Memberships

File: fake-data/membership.csv

Sample membership records.

ID Status Person Valid From Valid To Period ID Criteria ID

1

A

1 (Albert)

2018-03-17

2018-12-31

1

1

2

A

2 (Bertha)

2018-06-11

2018-12-31

1

1

3

A

3 (Charlie)

2018-08-02

2018-12-31

1

1

4

A

1 (Albert)

2018-11-14

2019-12-31

2

2

5

A

2 (Bertha)

2018-10-04

2019-12-31

2

2

6

P

3 (Charlie)

2019-01-01

2019-12-31

2

2

7

D

1 (Albert)

2020-01-01

2020-12-31

3

3

8

R

2 (Bertha)

2019-11-05

2020-12-31

3

3

9

A

9 (Isaac)

2020-01-01

2020-12-31

3

3

10

A

10 (Jack)

2020-02-11

2020-12-31

3

3

Status Codes:

  • A - Active

  • P - Pending

  • D - Declined

  • R - Renewal

4.10. Events

File: fake-data/event.csv

Test events for development and testing.

4.10.1. Legacy Events (Organisation 4 - WPCA)

ID Name Start Date/Time

1

Alfa Race

2020-01-01T07:00

2

Bravo Race

2020-01-01T07:00

3

Charlie Race

2020-01-01T07:00

4

Delta Race

2020-01-01T07:00

5

Echo Race

2020-01-01T07:00

6

Foxtrot Race

2020-01-01T07:00

7

Golf Race

2020-01-01T07:00

8

Hotel Race

2020-01-01T07:00

9

Lima Race

2020-01-01T07:00

10

Mike Race

2020-01-01T07:00

All legacy events (1-10) are set to:

  • Timezone: Africa/Johannesburg

  • Organiser: Organisation 4 (Western Province Cycling Association)

  • CSA membership required: true

4.10.2. 2025 Events (Organisation 4 - WPCA)

ID Name Date Enrol Process Notes

11

Spring Trail Run 2025

2025-03-15

6 (Trial Run)

12

Autumn Night Race 2025

2025-05-10

7 (Road Run)

Evening event 18:00-22:00

13

Winter Cross Country 2025

2025-07-12

8 (Hill Climb)

CSA membership required

4.10.3. 2025 Events (Organisation 9 - WC Schools Cycling)

ID Name Date Enrol Process Notes

14

Summer Series Final 2025

2025-11-22

9 (Crit Series)

CSA license required, strict registration

15

School XCO Championship 2025

2025-09-06

4 (School XCO)

All-day event

The enrol_process_id links events to process definitions for registration workflows. All event processes (4, 6-9) are of type E (Event).

4.11. Products

File: fake-data/product.csv

Pricing for membership and event entry.

ID Name Price Notes

1

Series entry

R200

2

Event entry - Adult

R350

3

Event entry - Youth

R120

4

Event entry - Senior

R220

5

Race number

R100

6

Timing tag

R350

Sale price R300

7

Adult Membership

R250

8

Child Membership

R50

9

Senior Membership

R150

10

Gift card

R100

11

Family Membership

R600

HNR family bundle

12

Early Riser Membership

R200

HNR early access

4.12. Process Definitions

File: fake-data/process_definition.csv

Workflow definitions for registration processes.

ID Name Type Purpose

1

UI Form Test

M

Membership form testing

2

UI Mockup

M

Membership UI prototype

3

HNR 2025

M

Helderberg Nature Reserve 2025

4

School XCO

E

School cross-country event

5

TTT

E

Team time trial event

6

Trial Run

E

Trial run event

7

Road Run

E

Road running event

8

Hill Climb

E

Hill climb event

9

Crit Series

E

Criterium series

10

HNR

M

Helderberg Nature Reserve general

Type Codes:

  • M - Membership registration

  • E - Event registration

4.13. Process Steps

File: fake-data/process_step.csv

Question definitions for process workflows.

4.13.1. Definition 1: UI Form Test

ID Type Description Required

1

TXT

School Name

Yes

2

SEL

ClubName

Yes

3

BCB

Buy a new number

Yes

4

ONE

Main Member

Yes

4.13.2. Definition 2: UI Mockup

ID Type Description Required

11

TXT

Club name

Yes

12

SEL

School

No

13

BCB

Order a replacement card

No

14

ONE

Select the main member

Yes

15

ITC

Indemnity

Yes

4.13.3. Definition 3: HNR 2025 (Family Membership)

ID Type Description Required

30

MFA

Family Membership - Select Adult

Yes

31

MFC

Family Membership - Select Children

Yes

32

MFM

Family Membership - Select main member

Yes

33

MCS

Early Riser Key

No

34

ITC

Indemnity

Yes

4.13.4. Definition 4: School XCO

ID Type Description Required

5

ERT

Event Type

Yes

6

CAT

Category

Yes

7

SEL

Club

No

8

SEL

School

Yes

9

ITC

Accept terms

Yes

10

CAT

Category

Yes

4.13.5. Definition 6: Trial Run

ID Type Description Required

40

CAT

Category

Yes

41

TXT

Emergency Contact

Yes

42

SEL

T-Shirt Size

No

43

ITC

Terms and Conditions

Yes

4.13.6. Definition 7: Road Run

ID Type Description Required

50

CAT

Category

Yes

51

SEL

Club

No

52

TXT

Emergency Contact

Yes

53

ITC

Terms and Conditions

Yes

4.13.7. Definition 8: Hill Climb

ID Type Description Required

60

CAT

Category

Yes

61

SEL

Club

No

62

BCB

Medical Conditions

No

63

TXT

Emergency Contact

Yes

64

ITC

Terms and Conditions

Yes

4.13.8. Definition 9: Crit Series

ID Type Description Required

70

CAT

Category

Yes

71

SEL

Club

No

72

TXT

Emergency Contact

Yes

73

BCB

Race Number

No

74

ITC

Terms and Conditions

Yes

4.13.9. Definition 10: HNR Legacy

ID Type Description Required

20

BCB

Medical conditions

No

21

TXT

Emergency contact

Yes

22

ONE

Primary contact

Yes

23

ITC

Terms and conditions

Yes

Question Types:

Code Name Description

TXT

Text Input

Free-form text entry

SEL

Selection

Dropdown selection from options

BCB

Binary Checkbox

Yes/No checkbox

ONE

Select One

Radio button selection (one person)

ITC

I Accept Terms

Terms and conditions acceptance

CAT

Category

Event category selection

ERT

Event Race Type

Event/race type selection

MFA

Membership Family Adult

Select adults for family bundle

MFC

Membership Family Child

Select children for family bundle

MFM

Membership Family Main

Select main member for family

MCS

Membership Cross-Sell

Cross-sell additional memberships

4.14. Process Step Options

File: fake-data/process_step_option.csv

Predefined options for selection-type questions.

ID Value Step ID

1-10

Club Alpha to Club Juliet

2 (ClubName)

11

Yes, I want to buy a new card.

3 (Buy new number)

12

North High

12 (School)

13

Southgate Primary

12 (School)

14

Yes, I want to buy a new card.

13 (Replacement card)

15

Main member

14 (Main member)

16

Yes, I accept the terms and conditions

15 (Indemnity)

4.15. Categories

File: fake-data/category.csv

Master category data owned by Organisation 4 (WPCA). Categories define age and gender restrictions for event entry.

ID Name Min Age Max Age Gender

Elite and Junior

1

Elite Men

19

49

M

2

Junior Men

17

18

M

16

Elite Female

19

49

F

17

Junior Female

17

18

F

Youth Categories - Boys

3

Under 11 Boys

5

10

M

4

Under 13 Boys

11

12

M

5

Under 15 Boys

13

14

M

6

Under 17 Boys

15

16

M

Youth Categories - Girls

18

Under 11 Girls

5

10

F

19

Under 13 Girls

11

12

F

20

Under 15 Girls

13

14

F

21

Under 17 Girls

15

16

F

Masters - Men

7

35-39 Men

35

39

M

8

40-44 Men

40

44

M

9

45-49 Men

45

49

M

10

50-54 Men

50

54

M

11

55-59 Men

55

59

M

12

60-64 Men

60

64

M

13

65-69 Men

65

69

M

14

70-74 Men

70

74

M

15

75+ Men

75

100

M

Masters - Female

22

35-39 Female

35

39

F

23

40-44 Female

40

44

F

24

45-49 Female

45

49

F

25

50-54 Female

50

54

F

26

55-59 Female

55

59

F

27

60-64 Female

60

64

F

28

65-69 Female

65

69

F

29

70-74 Female

70

74

F

30

75+ Female

75

100

F

Para Categories

31

Para C4

NULL

NULL

NULL

32

Para C3

NULL

NULL

NULL

33

Para C5

NULL

NULL

NULL

4.16. Event Categories

File: fake-data/event_category.csv

Event-specific category instances linked to master categories via source_category_id. Each event has its own set of categories.

ID Range Event Categories

1-33

Event 14 (Summer Series Final 2025)

All 33 cycling categories

34-66

Event 15 (School XCO Championship 2025)

All 33 cycling categories

Event Category Fields:

  • id - Unique identifier

  • name - Category name (copied from source)

  • min_age / max_age - Age restrictions

  • gender - Gender restriction (M/F/NULL)

  • race_category - Used for race classification (false)

  • entry_category - Used for event entry (true)

  • source_category_id - Link to master Category

  • event_id - Link to Event

5. Registration Portal Data

5.1. Authority

File: data/authority.csv

Standard security roles for the registration portal.

ROLE_ADMIN
ROLE_USER

5.2. Tenant

File: fake-data/tenant.csv

Tenant configuration for multi-tenant registration portals.

ID Name Domain Organisation

1-6

Registration 1-6

reg1-reg6

1-6

7

Localhost

localhost

7

8

Western Province Cycling Association

wpca

4 (WPCA)

9

Helderberg Nature Reserve

hnr

8 (HNR)

10

Western Cape School Cycling

wcsc

9 (WC Schools Cycling)

5.2.1. Tenant to Registration System Mapping

File: fake-data/tenant_registration_system_id.csv

Links tenants to their external registration systems for authentication.

Tenant ID Tenant Name Registration System

8

Western Province Cycling Association

1 (Wordpress1) → Org 4

9

Helderberg Nature Reserve

7 (HNR Website) → Org 8

10

Western Cape School Cycling

2 (WCSC Website) → Org 9

tenant-regsys-org

Tenant Fields:

  • id - Unique identifier

  • name - Tenant display name

  • domain - Tenant domain (used for routing)

  • organisation - Linked organisation ID

  • issuer_url - OIDC issuer URL (optional)

  • client_id / client_secret - OIDC credentials (optional)

  • scope - OIDC scope (optional)

  • theme - UI theme

  • header_image_url - Branding image

  • reset_redirect_name - Display name for the redirect link shown after session reset (optional)

  • reset_redirect_url - URL to redirect users to after session expiry or auth failure (optional)

5.2.2. Reset Redirect Configuration

File: fake-data/tenant_reset_redirect.csv

Test data for session reset redirect behaviour. When a user’s session expires or authentication fails, they can be redirected to a tenant-specific URL.

Tenant ID Reset Redirect Name Reset Redirect URL

8

Western Province Cycling Association Home page

https://wpca.local

9

HNR Membership page

https://hnr.local

10

WCSC Home page

https://wcsc.local

5.3. APIKey (admin-service)

File: admin-service/…​/changelog/20240204215400_add_entities_ApiKeys.xml (changeSet id 20240204215400-3)

API keys for authenticating client systems with admin-service. Loaded via faker context for development only.

ID Key Value Description

1

f283f35e-f813-4172-a7d5-a271c092f42c

Registration Portal

2

704ddda5-00a8-495c-9bc7-8753f3d391a8

Membership Admin

3

46294a90-5e4d-4c5b-8198-b331f8631f13

Admin Portal

These API keys enable the registration-portal gateway (BFF) to authenticate with admin-service APIs. The key_value is a UUID used as an authentication header.

6. Data Loading Order

Liquibase changelogs must load data in dependency order:

load-order

6.1. Circular Dependency: membership_period ↔ membership_criteria

There is a circular dependency between membership_period and membership_criteria:

  • membership_criteria.period_id → references membership_period

  • membership_period.default_criteria_id → references membership_criteria

Resolution: The default_criteria_id is set via a separate SQL UPDATE changeset that runs after both tables are populated:

  1. Load membership_period (without default_criteria_id)

  2. Load membership_criteria (with period_id references)

  3. Execute SQL UPDATE to set default_criteria_id values

This is implemented in fake-data.xml as changeset FAKE-132-membership_period_default_criteria.

-- Example: Set default criteria for periods with process-driven registration
UPDATE membership_period SET default_criteria_id = 2 WHERE id = 1;   -- Period 1 → Adult criteria
UPDATE membership_period SET default_criteria_id = 24 WHERE id = 21; -- Period 21 → Adult criteria

7. Testing External Authentication

This section describes how to test external authentication using the test data defined above.

7.1. Registration Portal Testing

The registration-portal provides a simplified authentication endpoint that resolves the tenant from the Host header or X-TENANT-ID header. This is the recommended approach for testing the full authentication flow.

Endpoint: POST /api/auth/external-login

Required Headers:

  • Content-Type: application/json

  • Host: <tenant-domain> - Tenant domain for context resolution (e.g., hnr, wpca, wcsc), OR

  • X-TENANT-ID: <tenant-id> - Tenant ID for context resolution (e.g., 9 for HNR)

Request Body:

{
  "userId": "<external_user_id>",
  "userHash": "<md5_hash>"
}
The registrationSystemId is resolved automatically from the tenant context.

7.1.1. Helderberg Nature Reserve (Tenant 9)

# User 1 (Albert Allison) - using X-TENANT-ID header
curl -v http://localhost:12505/api/auth/external-login \
  -H "Content-Type: application/json" \
  -H "X-TENANT-ID: 9" \
  -c cookies.txt \
  -d '{"userId": "1", "userHash": "6f7b1a88fb18965daef7e07bd17b3c8a"}'

# User 7 (Gail Geldenhuys)
curl -v http://localhost:12505/api/auth/external-login \
  -H "Content-Type: application/json" \
  -H "X-TENANT-ID: 9" \
  -c cookies.txt \
  -d '{"userId": "7", "userHash": "8ee92b84eed7dab1215c33fcba777fa2"}'

7.1.2. Western Province Cycling Association (Tenant 8)

# User 3 (Charlie Chesterton)
curl -v http://localhost:12505/api/auth/external-login \
  -H "Content-Type: application/json" \
  -H "X-TENANT-ID: 8" \
  -c cookies.txt \
  -d '{"userId": "3", "userHash": "d6a0f7e0d17dde474623d6ca74dac912"}'

# User 15 (Olivia Owens)
curl -v http://localhost:12505/api/auth/external-login \
  -H "Content-Type: application/json" \
  -H "X-TENANT-ID: 8" \
  -c cookies.txt \
  -d '{"userId": "15", "userHash": "561c2f60fdb05ec83570934a477878aa"}'

7.1.3. Western Cape Schools Cycling (Tenant 10)

Currently no org_user records are linked to organisation 9. To test this tenant, add org_user records linking users to organisation 9.

7.1.4. Expected Response

A successful authentication returns HTTP 200 with an empty body. The JWT is stored in the server-side session (not exposed to the client).

HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=...; Path=/; HttpOnly

Subsequent requests to protected endpoints will use the session cookie to relay the JWT to admin-service.

7.2. Admin Service Testing

For debugging or integration testing, you can call admin-service directly. This bypasses tenant resolution and requires explicit registrationSystemId and API key.

These examples are for direct admin-service testing only. In production, authentication flows through the registration-portal gateway.

Prerequisites:

  • admin-service running on localhost:12504

  • Database loaded with faker context (test data)

  • API key from test data: f283f35e-f813-4172-a7d5-a271c092f42c

Endpoint: POST /auth/external-login

Required Headers:

  • Content-Type: application/json

  • X-API-KEY: <api-key> - API key for service authentication

Request Body:

{
  "userId": "<external_user_id>",
  "registrationSystemId": <registration_system_id>,
  "userHash": "<md5_hash>"
}

7.2.1. Helderberg Nature Reserve (RegSystem 7 → Org 8)

# User 1 (Albert Allison)
curl -v http://localhost:12504/auth/external-login \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: f283f35e-f813-4172-a7d5-a271c092f42c" \
  -d '{"userId": "1", "registrationSystemId": 7, "userHash": "6f7b1a88fb18965daef7e07bd17b3c8a"}'

# User 7 (Gail Geldenhuys)
curl -v http://localhost:12504/auth/external-login \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: f283f35e-f813-4172-a7d5-a271c092f42c" \
  -d '{"userId": "7", "registrationSystemId": 7, "userHash": "8ee92b84eed7dab1215c33fcba777fa2"}'

7.2.2. Western Province Cycling Association (RegSystem 1 → Org 4)

# User 3 (Charlie Chesterton)
curl -v http://localhost:12504/auth/external-login \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: f283f35e-f813-4172-a7d5-a271c092f42c" \
  -d '{"userId": "3", "registrationSystemId": 1, "userHash": "d6a0f7e0d17dde474623d6ca74dac912"}'

# User 15 (Olivia Owens)
curl -v http://localhost:12504/auth/external-login \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: f283f35e-f813-4172-a7d5-a271c092f42c" \
  -d '{"userId": "15", "registrationSystemId": 1, "userHash": "561c2f60fdb05ec83570934a477878aa"}'

7.2.3. Expected Response

A successful authentication returns a JWT token:

{
  "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}

The JWT contains claims including:

  • sub - External user ID

  • accountId - OrgUser ID

  • personId - Person ID

  • orgId - Organisation ID (resolved from RegistrationSystem)

  • linkedPersons - Array of linked person claims with access levels

  • linkedOrgs - Array of linked organisation claims with access levels

7.3. Common Errors

Status Error Cause

400

RegistrationSystem not found

Invalid registrationSystemId (admin-service) or tenant not found (registration-portal)

400

User not found

User not linked to the organisation associated with the registration system

400

Invalid authentication hash

Hash doesn’t match expected value for userId

401

Unauthorized

Missing or invalid X-API-KEY header (admin-service only)