Design and implement identifier mapping models using identity-lib (CHRIS, CAMSIS, CRSid)
As an integration developer consuming the Identifiers API,
I would like CHRIS and CAMSIS identifiers to be modelled and validated as mappings to CRSids
using the shared identity-lib,
so that identifier data is stored consistently
and can be safely read and written via the API.
Background
- The Identifiers API is currently an empty Django REST Framework application based on the UIS webapp boilerplate.
- This issue ticket requires the API to:
- Allow submission of mappings from CHRIS and CAMSIS identifiers to CRSids.
- Allow reading of previously submitted identifier mappings.
- The
identity-libprovides the canonical identifier scheme definitions and parsing utilities:- CHRIS staff number:
IdentifierSchemes.STAFF_NUMBER - CAMSIS USN:
IdentifierSchemes.USN - CRSid:
IdentifierSchemes.CRSID/CRSID_SCHEME -
IdentifierandIdentifierSchemes.from_string(...)should be used to normalise and validate identifier values (e.g. lowercase CRSid).
- CHRIS staff number:
- A robust data model is needed in the Identifiers API Django app to:
- Represent mappings between “source” identifiers (CHRIS / CAMSIS) and “target” identifiers (CRSid).
- Enforce uniqueness and consistency (no duplicate/conflicting mappings).
- Provide timestamps and basic metadata required for retention rules and auditing in later stories.
- The model(s) designed here will be the foundation for the read/write API endpoints, authorisation, and auditing in subsequent tasks.
Acceptance Criteria
-
A Django model (or set of models) exists in the Identifiers API app to represent mappings from: - CHRIS (staff number) → CRSid, and
- CAMSIS (USN) → CRSid,
using the identifier schemes defined in
identity-lib.
-
The mapping model(s) store, at minimum: - Source identifier value.
- Source identifier scheme.
- Target identifier value.
- Target identifier scheme.
- Creation timestamp.
- Last-updated timestamp.
-
The mapping model(s) are generic enough to support multiple identifier schemes, but are explicitly validated to accept: -
IdentifierSchemes.STAFF_NUMBERas a valid source scheme. -
IdentifierSchemes.USNas a valid source scheme. -
IdentifierSchemes.CRSIDas the required target scheme.
-
-
Identifier values persisted to the database are normalised using identitylib.identifiers.IdentifierandIdentifierSchemes(e.g. CRSid values are stored in lowercase). -
Appropriate uniqueness constraints/indexes are defined to prevent duplicate mappings for the same source identifier and scheme (e.g. unique on (source_scheme, source_value, target_scheme)). -
A migration is created and committed that creates the identifier mapping tables in the database. -
Model-level validation prevents saving records with: - Invalid or unknown identifier schemes (not resolvable by
IdentifierSchemes.from_string). - Malformed identifier values that cannot be parsed or normalised by
Identifier.
- Invalid or unknown identifier schemes (not resolvable by
-
Unit tests exist for the model(s) covering at least: - Successful creation of CHRIS→CRSid mappings.
- Successful creation of CAMSIS→CRSid mappings.
- Enforcement of uniqueness constraints.
- Normalisation behaviour (e.g. CRSid lowercasing).
- Rejection of invalid schemes or malformed identifiers.
-
Basic documentation is added describing (see https://gitlab.developers.cam.ac.uk/uis/devops/iam/card-database/card-api/-/issues/287): - The identifier mapping model(s) and their purpose.
- How
identity-libis used for schemes and parsing. - Which schemes are currently supported (CHRIS, CAMSIS, CRSid).
Edited by Eugene E.