CSA Compliance Administration
1. Overview
A sanctioned event requires every rider to hold a Cycling South Africa (CSA) membership, a licence, or a day licence. Registration checks this with CSA while the rider enters, and records the outcome on the entry as a compliance status.
Most entries need no attention: CSA confirms the rider, or the rider buys a day licence. This procedure covers the rest — the entries CSA could not confirm — and produces one outcome:
Before event day, every entry is either confirmed compliant, or is known to the organiser as one that is not.
Run it from the day registration opens until event day. The sweep in The sweep takes a few minutes and is safe to repeat.
|
Today this procedure runs through the REST API for reading and through SQL for recording a decision. There is no screen for it. See Limitations of the current design. For how the checks themselves work — the CSA API, the three registration steps, and how a status is derived — see CSA Integration. This page is about operating the result. |
2. Choosing the event’s CSA settings
The settings are columns on the event row, created in
Configure an Event. They decide which checks run and which options a
rider is offered when a check does not pass.
| Setting | Default | Effect |
|---|---|---|
|
off |
The membership check runs. Without it no rider is checked and every entry is |
|
off |
The licence check runs as well. A licence depends on a membership, so set this only together
with |
|
off |
Removes I’ll provide proof later. A rider can no longer defer on their own word. Request review stays available, because a review by an administrator is a verification. |
|
off |
Removes Purchase Day License. Set it only for an event where a day licence is not accepted. |
|
off |
Lets a rider who supplied a UCI ID claim an international licence in place of a CSA licence. Every such entry needs a desk check. |
|
empty |
The product charged for a day licence. It is taken from the event, or from the series when the event has none. While neither has one, a rider can choose a day licence and is charged nothing for it. |
csa_membership_required, csa_license_required and allow_uci_license can also be set on a
series and on an event category. The most specific value wins: category, then event, then series. A
category left empty inherits from its event.
Two things must also be true, or the settings have no effect:
-
The event has an enrolment process (
event.enrol_process_id) that contains the CSA steps. -
The rider reaches those steps, which means the category they chose requires the check.
2.1. Which combination to choose
| The organiser wants | Set |
|---|---|
Every rider verified or paying for a day licence, with no exceptions on trust |
|
The same, and riders may promise proof later |
|
Licensed racing, where a day licence is not accepted |
|
A social event with no CSA requirement |
Nothing. |
Strict registration increases the number of entries that ask for a review, because a rider who cannot be confirmed has fewer other ways forward. Plan to run the sweep more often.
3. What a rider is offered
The rider first identifies themselves: a CSA number, a UCI ID, or None. A South African rider whose ID number CSA recognises is identified without entering anything. None is a decision to buy a day licence.
The membership check then offers options according to what CSA answered.
| CSA answered | Options offered |
|---|---|
Active |
Proceed. |
Expired or inactive |
Renew CSA Membership. Purchase Day License. I’ll provide proof later. Remove from registration. |
Not found |
Purchase Day License. Request review. Remove from registration. |
The CSA number was found, but its identity number differs from the rider’s |
Purchase Day License. Request review, for a rider whose identity document is not a South African ID. Remove from registration. |
No answer, CSA could not be reached |
Request review. Remove from registration. |
Suspended |
Remove from registration. |
Purchase Day License is absent when the event disallows day licences. I’ll provide proof later is absent under strict registration.
The licence check offers the same kinds of option, plus Purchase license and retry when no licence is found.
|
When several riders are entered by one person, such as a team manager, that person makes these choices for each rider. The rider may not know which option was chosen. |
4. Reading the compliance status
Each entry carries compliance_status, and two columns that mark it for review:
requires_admin_review and admin_review_reason.
| Status | How the entry got it | Flagged | What it needs |
|---|---|---|---|
|
CSA confirmed the rider. |
no |
Nothing. |
|
The event or category requires no check. |
no |
Nothing. |
|
The rider chose a day licence, or answered None. |
no |
Reporting to CSA by the organiser. See Reporting day licences to CSA. |
|
The rider chose Request review. |
yes |
A decision. See Vetting an entry. |
|
The rider claimed a UCI licence. |
yes |
A desk check of the licence. |
|
The rider chose I’ll provide proof later. |
no |
Proof from the rider. Nothing prompts for it. |
|
The rider chose Renew or Purchase, intending to put it right at CSA. |
no |
Confirmation that the rider did. Nothing prompts for it. |
Where the membership and licence checks disagree, the entry takes the first of these that applies:
DAY_LICENSE, UCI_PROVISIONAL, REVIEW_REQUESTED, DEFERRED. It is VALID only when every
check that ran ended in Proceed.
The review reason says why the rider could not be confirmed.
| Reason | Meaning |
|---|---|
|
The CSA number exists, and CSA reports that it does not carry the identity number on the rider’s profile. |
|
CSA has no record for the number or identity number supplied. |
|
CSA did not answer when the rider registered. |
|
The rider claimed an international licence. |
5. The sweep
-
List the entries waiting for a decision.
-
List the entries that need follow-up but are on no list.
-
Vet each one, as in Vetting an entry.
-
Record each decision, as in Recording an approval.
5.1. Entries waiting for a decision
Through the API:
GET /api/event-participants?eventId.equals=<event>&requiresAdminReview.equals=true&page=0&size=100
The endpoint is paginated. Repeat with page=1, page=2, and so on until a page is empty, or use the SQL query below for the complete list.
Add adminReviewReason.equals=<reason> to take one reason at a time.
Through SQL, with the order state beside each entry. An entry on an order that is not paid needs no decision yet.
SELECT ep.id, ep.first_name, ep.last_name,
ep.identity_type, ep.identity_country,
ep.admin_review_reason,
so.number AS order_number, so.status AS order_status
FROM event_participant ep
LEFT JOIN order_line_item oli ON oli.event_participant_id = ep.id
LEFT JOIN sales_order so ON so.id = oli.order_id
WHERE ep.event_id = <event>
AND ep.requires_admin_review = 1
GROUP BY ep.id, so.id
ORDER BY ep.admin_review_reason, ep.last_name;
sales_order.status is P for paid. The codes are listed in
Pre-Event Data Hygiene.
5.2. Entries on no list
PENDING and DEFERRED entries are not flagged, so the first query never returns them.
SELECT ep.id, ep.first_name, ep.last_name, ep.compliance_status,
so.number AS order_number, so.status AS order_status
FROM event_participant ep
JOIN order_line_item oli ON oli.event_participant_id = ep.id
JOIN sales_order so ON so.id = oli.order_id
WHERE ep.event_id = <event>
AND ep.compliance_status IN ('PENDING', 'DEFERRED')
AND so.status = 'P'
GROUP BY ep.id, so.id
ORDER BY ep.compliance_status, ep.last_name;
5.3. What the rider answered
The answer given at each step is kept with the registration, including the CSA number the rider typed. Use it when the entry alone does not explain the status.
SELECT ps.name AS step, pd.data_value
FROM event_participant ep
JOIN process_data pd ON pd.instance_id = ep.enrol_instance_id
AND pd.person_id = ep.person_id
JOIN process_step ps ON ps.id = pd.step_id
WHERE ep.id = <entry>
ORDER BY ps.seq;
6. Vetting an entry
Vetting is a check made outside the system. The system cannot confirm these riders, which is why they are in the queue.
A review request is not evidence of membership. A rider whom CSA does not know is offered a day licence and a review side by side, and the review costs nothing.
6.1. Asking CSA again
Start by repeating the check. A rider who was unknown when they registered may have joined since.
POST /api/csa/check-membership
{ "idNumber": "<identity number>", "date": "<event date>" }
Send csaId in place of idNumber to look up a CSA number, or send both to have CSA compare
them. The answer carries the status on that date, the CSA number, and the member’s club and region.
It does not carry the member’s name, so it cannot show on its own that a number belongs to the
rider.
6.2. Looking for the number on another profile
The same rider may have a second profile that already carries the CSA number. A matching name, date of birth and club is good evidence that the number is theirs.
SELECT u.ID, u.display_name,
(SELECT meta_value FROM wp_usermeta
WHERE user_id = u.ID AND meta_key = 'date_of_birth' LIMIT 1) AS date_of_birth,
(SELECT meta_value FROM wp_usermeta
WHERE user_id = u.ID AND meta_key = 'csa_club_name' LIMIT 1) AS club
FROM wp_usermeta um
JOIN wp_users u ON u.ID = um.user_id
WHERE um.meta_key = 'csa_id'
AND um.meta_value = '<csa number>';
6.3. By review reason
| Reason | How to vet |
|---|---|
|
CSA records South African ID numbers only. For a rider who registered with a passport, the comparison cannot succeed, so the reason says nothing against the rider. Confirm with CSA, or from the rider’s CSA membership card, that the CSA number belongs to this person. A rider who registered with a South African ID is not offered a review on a mismatch. For them it means the CSA number belongs to someone else, or was mistyped. |
|
Read the number the rider typed. A mistyped number is the usual cause. Ask the rider for their CSA membership card and compare. |
|
CSA was unreachable at the time, so nothing is known about the rider. Look the rider up at CSA now. |
|
Sight the licence. Confirm it is current on the day of the event and covers the discipline. |
For a PENDING entry, confirm with CSA that the membership is now active. For a DEFERRED entry,
obtain the proof the rider promised.
6.4. What to look out for
-
A foreign rider recorded with a South African identity type. They are offered no review, only a day licence or removal. Correct the identity type on the profile before they register again.
-
A rider identified by ID number. The check used the ID number alone. A CSA number stored on the rider’s profile was not consulted, and may belong to a different, current membership.
-
Two profiles for one person. The same rider can exist twice, once with a passport and once with an ID number. The entry follows whichever profile was used to register.
-
A missing expiry date. CSA reports that a membership has expired, and does not always say when.
7. Recording an approval
An approval sets the entry to VALID and clears the review flag. Run the statement on the
read/write connection, one entry at a time.
UPDATE event_participant
SET compliance_status = 'VALID',
requires_admin_review = 0,
admin_review_reason = NULL,
modified_by = 'manual-review',
modified_on = NOW(3)
WHERE id = <entry>
AND event_id = <event>
AND compliance_status = 'REVIEW_REQUESTED'
AND admin_review_reason = '<reason>';
-
Confirm that exactly one row changed. The last two conditions make the statement do nothing if the entry has moved on since it was listed.
-
Evict the caches, as in Cache Management. Entries are cached, so the API can return the old status until this is done.
-
Read the entry back through the API and confirm
complianceStatusisVALIDandrequiresAdminReviewisfalse. -
Run the first query of The sweep again and confirm the entry has left the queue.
For a UCI_PROVISIONAL, PENDING or DEFERRED entry, change the condition on
compliance_status to match and drop the condition on admin_review_reason.
An entry that cannot be confirmed stays as it is. What happens to the rider is the organiser’s decision, and is not recorded by this procedure.
8. Before event day
-
The review queue for the event is empty.
-
Every
PENDINGandDEFERREDentry has been followed up. -
The day licences are ready to report, as in Reporting day licences to CSA.
9. Reporting day licences to CSA
The system collects the day licence fee from the rider. It does not issue the licence. The organiser reports the riders who bought one to CSA, CSA invoices the organiser for them, and the organiser pays the invoice.
Issuing a licence at CSA from the system exists behind the setting
csa.api.day-license-issuance-enabled, which is switched off. See
Configure an Event.
The report is the list of paid entries with a day licence:
SELECT ep.id, ep.first_name, ep.last_name, ep.date_of_birth, ep.gender,
so.number AS order_number
FROM event_participant ep
JOIN order_line_item oli ON oli.event_participant_id = ep.id
JOIN sales_order so ON so.id = oli.order_id
WHERE ep.event_id = <event>
AND ep.compliance_status = 'DAY_LICENSE'
AND so.status = 'P'
GROUP BY ep.id, so.id
ORDER BY ep.last_name;
10. Limitations of the current design
-
There is no screen for the review queue. It is read through the API or SQL.
-
An approval is recorded by SQL.
PATCH /api/event-participants/{id}does clear the review flag when the status changes, but a request that leaves out the entry’s race types and teams removes them, and the entry drops out of its races. -
That endpoint requires access to both the organisation and the person. An administrator of the organising body is refused. Only a platform administrator passes.
-
An approval keeps no record of who vetted the rider or what was sighted. Clearing the flag also clears the reason. The rider’s original answer remains with the registration.
-
PENDINGandDEFERREDentries raise no flag and appear in no queue. -
No check is repeated after registration. A rider who renews at CSA the next day stays
PENDINGuntil an operator changes it. -
A rider entered by someone else is not told which option was chosen for them.
-
The order of the steps in an enrolment process is not validated. The checks assume the category and race type are answered first and that the membership check precedes the licence check — see Step order.