FAQ | This is a LIVE service | Changelog

Skip to content

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-lib provides the canonical identifier scheme definitions and parsing utilities:
    • CHRIS staff number: IdentifierSchemes.STAFF_NUMBER
    • CAMSIS USN: IdentifierSchemes.USN
    • CRSid: IdentifierSchemes.CRSID / CRSID_SCHEME
    • Identifier and IdentifierSchemes.from_string(...) should be used to normalise and validate identifier values (e.g. lowercase CRSid).
  • 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_NUMBER as a valid source scheme.
    • IdentifierSchemes.USN as a valid source scheme.
    • IdentifierSchemes.CRSID as the required target scheme.
  • Identifier values persisted to the database are normalised using identitylib.identifiers.Identifier and IdentifierSchemes (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.
  • 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-lib is used for schemes and parsing.
    • Which schemes are currently supported (CHRIS, CAMSIS, CRSid).
Edited by Eugene E.