flip_api.trusts_services.services.register_trust ================================================ .. py:module:: flip_api.trusts_services.services.register_trust .. autoapi-nested-parse:: Trust registration service — the single write path into the `trust` table. Two callers: - ``POST /admin/trusts`` (``trusts_services.admin_create_trust``) for one-off admin-driven registrations from the UI. - ``flip_api.scripts.register_trust`` CLI, invoked once per trust by the deploy Makefile's ``register-trust`` target (the trust's name comes from its kit file; the hub keeps no trust list of its own). Both produce the same on-disk state: one ``Trust`` row with ``api_key_hash`` set, one ``FLKitSlot`` assigned, plaintext api/internal-service keys returned once for distribution to the trust host (then unrecoverable). Exceptions ---------- .. autoapisummary:: flip_api.trusts_services.services.register_trust.TrustRegistrationError flip_api.trusts_services.services.register_trust.EmptyTrustNameError flip_api.trusts_services.services.register_trust.EmptyTrustCodeError flip_api.trusts_services.services.register_trust.DuplicateTrustError flip_api.trusts_services.services.register_trust.NoFreeKitSlotError Classes ------- .. autoapisummary:: flip_api.trusts_services.services.register_trust.RegisteredTrust Functions --------- .. autoapisummary:: flip_api.trusts_services.services.register_trust.register_trust Module Contents --------------- .. py:exception:: TrustRegistrationError Bases: :py:obj:`Exception` Base for trust registration failures. .. py:exception:: EmptyTrustNameError Bases: :py:obj:`TrustRegistrationError` Caller supplied a blank trust name. .. py:exception:: EmptyTrustCodeError Bases: :py:obj:`TrustRegistrationError` Caller supplied a blank (or missing) trust code — code is required. .. py:exception:: DuplicateTrustError Bases: :py:obj:`TrustRegistrationError` A trust with the given name already exists. .. py:exception:: NoFreeKitSlotError Bases: :py:obj:`TrustRegistrationError` The FL kit slot pool is exhausted. .. py:class:: RegisteredTrust Result of a successful registration — the only place plaintext keys exist. Plaintext ``trust_api_key`` and ``trust_internal_service_key`` are returned exactly once: the hub stores only the api-key's SHA-256 hash, and the internal-service key is never persisted hub-side. .. py:attribute:: trust :type: flip_api.db.models.main_models.Trust .. py:attribute:: fl_kit_slot :type: flip_api.db.models.main_models.FLKitSlot .. py:attribute:: trust_api_key :type: str .. py:attribute:: trust_internal_service_key :type: str .. py:function:: register_trust(name: str, code: str | None, region: str | None, session: sqlmodel.Session, audit_user_id: uuid.UUID | None = None) -> RegisteredTrust Atomically register a trust: mint keys, claim an FL kit slot, insert the row. :param name: Friendly display name (any non-empty string after strip). :type name: str :param code: Short code (e.g. ``GSTT``). Required — must be non-empty after strip. Names are arbitrary/non-unique, so the code is the stable short handle used in kit filenames and operator tooling. :type code: str | None :param region: Optional NHS region. :type region: str | None :param session: SQLModel session; the function commits before returning. :type session: Session :param audit_user_id: Cognito sub of the authenticated admin from the UI path, or ``None`` for the deploy-CLI path (which runs under operator IAM, not a FLIP user). Stamped on the ``trusts_audit`` row written in the same transaction as the trust insert. :type audit_user_id: UUID | None :returns: The persisted trust, its assigned FL kit slot, and the plaintext api / internal-service keys (returned once — discard from memory immediately after handing them to the operator). :rtype: RegisteredTrust :raises EmptyTrustNameError: ``name.strip()`` is empty. :raises EmptyTrustCodeError: ``code`` is missing or empty after strip. :raises DuplicateTrustError: A trust with this name already exists. :raises NoFreeKitSlotError: The ``fl_kit_slot`` pool has no unassigned rows.