openapi: 3.1.1
info:
  title: Energy Enrollment — Enrollment Attributes (v0.2)
  version: 0.2.0
  x-profile-id: profiles/energy-onboarding/energy_enrollment/v0.2/enrollment
  description: >
    Attribute schemas for program enrollment (Fulfillment.fulfillmentAttributes and Order.orderAttributes).
    These attributes support the onboarding flow where BPP verifies credentials, checks for conflicts,
    and issues enrollment credentials. Used in init requests (fulfillmentAttributes) and init/confirm
    responses (orderAttributes).

components:
  schemas:
    ########################################################################
    # FULFILLMENT.ATTRIBUTES & ORDER.ATTRIBUTES — EnergyEnrollment
    ########################################################################
    EnergyEnrollment:
      type: object
      additionalProperties: true
      x-jsonld:
        "@context": ./context.jsonld
        "@type": EnergyEnrollment
      description: >
        Main schema for enrollment attributes. Used in:
        - fulfillmentAttributes (init request): Contains credentials and existingEnrollments
        - orderAttributes (on_init response): Contains credentialVerification and conflictCheck
        - orderAttributes (confirm request): Contains startDate and endDate
        - orderAttributes (on_confirm response): Contains full enrollment details including credential
      properties:

        # Used in orderAttributes for user authentication
        userAuth:
          description: >
            User authentication for enrollment verification.
            Supports OTP-based or OAuth2/OIDC token-based authentication.
            
            For REQUESTS (init, confirm):
              Use UserAuthRequest (OtpAuthRequest or OAuth2AuthRequest)
              - OTP: Send mobile (init) or mobile+nguid+otp (confirm)
              - OAuth2/OIDC: Send accessToken (and idToken for OIDC)
            
            For RESPONSES (on_init, on_confirm):
              Use UserAuthResponse (OtpAuthResponse or OAuth2AuthResponse)
              - Returns verification status, extracted identity, and session tokens
          oneOf:
            - $ref: '#/components/schemas/UserAuthRequest'
            - $ref: '#/components/schemas/UserAuthResponse'
          x-jsonld: { "@id": userAuth }

        # Used in orderAttributes (confirm request) - meters to enroll
        meters:
          type: array
          description: >
            Array of meter identifiers to enroll in the program.
            Required in confirm request - order will only be confirmed if at least one meter is specified.
            Each meter should include the meter ID (UMID) and optionally utility information.
            If userAuth is verified but meters array is empty, on_confirm returns error "no meter specified".
          items:
            $ref: '#/components/schemas/MeterEnrollment'
          x-jsonld: { "@id": meters, "@container": "@set" }

        # Used in fulfillmentAttributes (init request)
        credentials:
          type: array
          description: >
            Array of W3C Verifiable Credentials (https://www.w3.org/TR/vc-data-model-2.0/) provided by calling entity (Portal/BAP).
            Includes meter ownership, program eligibility, and DER certification credentials.
          items:
            $ref: '#/components/schemas/VerifiableCredential'
          x-jsonld: { "@id": credentials }

        existingEnrollments:
          type: array
          description: >
            Array of existing W3C Verifiable Credentials for conflict checking.
            Provided by calling entity to help BPP identify conflicts.
          items:
            $ref: '#/components/schemas/VerifiableCredential'
          x-jsonld: { "@id": existingEnrollments }

        # Used in orderAttributes (on_init response)
        credentialVerification:
          type: object
          description: >
            Results of credential verification performed by BPP.
            Returned in on_init response after BPP verifies provided credentials.
          x-jsonld:
            "@id": credentialVerification
            "@type": CredentialVerification
          properties:
            status:
              type: string
              enum: [VERIFIED, FAILED, PARTIAL]
              description: Overall verification status. VERIFIED if all credentials verified, FAILED if any failed, PARTIAL if some verified.
              example: "VERIFIED"
              x-jsonld: { "@id": status }
            verifiedCredentials:
              type: array
              description: Array of credentials that were successfully verified.
              items:
                $ref: '#/components/schemas/VerifiedCredential'
              x-jsonld: { "@id": verifiedCredentials }

        conflictCheck:
          type: object
          description: >
            Results of conflict checking with existing enrollments.
            Returned in on_init response after BPP checks for conflicts.
          x-jsonld:
            "@id": conflictCheck
            "@type": ConflictCheck
          properties:
            hasConflict:
              type: boolean
              description: >
                Boolean indicating if a conflict exists. True if meter/DER is already enrolled
                in another program with overlapping dates, false otherwise.
              example: false
              x-jsonld: { "@id": hasConflict }
            conflictingEnrollments:
              type: array
              description: >
                Array of conflicting enrollments. Only present when hasConflict is true.
                Empty array if no conflicts found.
              items:
                $ref: '#/components/schemas/ConflictingEnrollment'
              x-jsonld: { "@id": conflictingEnrollments }
            checkedAt:
              type: string
              format: date-time
              description: Timestamp when conflict check was performed (ISO 8601 UTC).
              example: "2024-10-15T10:30:05Z"
              x-jsonld: { "@id": checkedAt }
            message:
              type: string
              description: Human-readable message explaining conflict check results.
              example: "No conflicts found with existing enrollments"
              x-jsonld: { "@id": message }

        requiredCredentials:
          type: array
          description: >
            Array of credential types that are required for enrollment.
            Returned in on_init response to inform BAP what credentials are needed.
            Each entry includes type, description, and status (PROVIDED, MISSING).
          items:
            type: object
            additionalProperties: true
            description: Required credential object with type, description, and status
          x-jsonld: { "@id": requiredCredentials }

        requiredConsents:
          type: array
          description: >
            Array of consent types that are required for enrollment.
            Returned in on_init response to inform BAP what consents are needed.
            Each entry includes type, description, and whether it's required or optional.
          items:
            type: object
            additionalProperties: true
            description: Required consent object with type, description, and required flag
          x-jsonld: { "@id": requiredConsents }

        # Used in orderAttributes (confirm request)
        startDate:
          type: string
          format: date-time
          description: >
            Date and time when enrollment becomes active (ISO 8601 UTC).
            Specified by calling entity in confirm request, returned in on_confirm response.
          example: "2024-11-01T00:00:00Z"
          x-jsonld: { "@id": startDate }

        endDate:
          type: string
          format: date-time
          description: >
            Date and time when enrollment expires or ends (ISO 8601 UTC).
            Specified by calling entity in confirm request, returned in on_confirm response.
          example: "2025-10-31T23:59:59Z"
          x-jsonld: { "@id": endDate }

        consents:
          type: array
          description: >
            Array of consent objects provided by the buyer in confirm request.
            Each consent indicates the type of consent and whether it was granted.
          items:
            type: object
            additionalProperties: true
            description: Consent object with type, granted status, grantedAt timestamp, and description
          x-jsonld: { "@id": consents }

        # Used in orderAttributes (update request/response)
        updateType:
          type: string
          enum: [CONSENT_REVOCATION, UNENROLLMENT]
          description: >
            Type of update being performed. CONSENT_REVOCATION for revoking consent,
            UNENROLLMENT for cancelling entire enrollment.
          example: "CONSENT_REVOCATION"
          x-jsonld: { "@id": updateType }

        consentRevocation:
          type: object
          description: >
            Consent revocation details. Used in update request to revoke a consent credential,
            and in on_update response to confirm revocation with status list information.
          x-jsonld:
            "@id": consentRevocation
            "@type": ConsentRevocation
          properties:
            consentCredentialId:
              type: string
              format: uri
              description: >
                Identifier of the consent credential being revoked. References the Verifiable Credential ID.
              example: "https://vpp-program-owner.example.com/credentials/vc:consent:consumer-001"
              x-jsonld: { "@id": consentCredentialId }
            consentType:
              type: string
              enum: [DATA_COLLECTION, DER_CONTROL, CROSS_UTILITY_SHARING]
              description: >
                Type of consent being revoked. DATA_COLLECTION for data sharing consent,
                DER_CONTROL for device control consent, CROSS_UTILITY_SHARING for cross-utility data sharing.
              example: "DATA_COLLECTION"
              x-jsonld: { "@id": consentType }
            reason:
              type: string
              description: >
                Reason for revocation. Values: USER_REQUESTED, PROGRAM_TERMINATED, COMPLIANCE_REQUIREMENT, etc.
              example: "USER_REQUESTED"
              x-jsonld: { "@id": reason }
            revokedAt:
              type: string
              format: date-time
              description: >
                Timestamp when the consent was revoked (ISO 8601 UTC).
                In request, this is when user initiated revocation. In response, this is when BPP processed it.
              example: "2024-11-20T14:30:00Z"
              x-jsonld: { "@id": revokedAt }
            effectiveDate:
              type: string
              format: date-time
              description: >
                Date and time when the revocation becomes effective (ISO 8601 UTC).
                May be in the future for scheduled revocations.
              example: "2024-11-20T14:30:00Z"
              x-jsonld: { "@id": effectiveDate }
            status:
              type: string
              enum: [REVOKED, PENDING]
              description: >
                Revocation status. REVOKED when processed, PENDING when scheduled for future.
                Only present in on_update response.
              example: "REVOKED"
              x-jsonld: { "@id": status }
            statusListUrl:
              type: string
              format: uri
              description: >
                URL of the W3C VC status list where the revoked credential is recorded.
                Only present in on_update response after revocation is processed.
              example: "https://vpp-program-owner.example.com/status/consent-list"
              x-jsonld: { "@id": statusListUrl }
            statusListIndex:
              type: string
              description: >
                Index in the status list where this credential's revocation status is recorded.
                Only present in on_update response.
              example: "94567"
              x-jsonld: { "@id": statusListIndex }
            message:
              type: string
              description: >
                Human-readable message about the revocation status.
                Only present in on_update response.
              example: "Consent has been revoked and added to revocation status list."
              x-jsonld: { "@id": message }

        unenrollment:
          type: object
          description: >
            Unenrollment details. Used in update request to cancel enrollment,
            and in on_update response to confirm cancellation with status list information.
          x-jsonld:
            "@id": unenrollment
            "@type": Unenrollment
          properties:
            enrollmentId:
              type: string
              description: >
                Identifier of the enrollment being cancelled.
              example: "enrollment-consumer-001"
              x-jsonld: { "@id": enrollmentId }
            reason:
              type: string
              description: >
                Reason for unenrollment. Values: USER_REQUESTED, PROGRAM_TERMINATED, COMPLIANCE_REQUIREMENT, etc.
              example: "USER_REQUESTED"
              x-jsonld: { "@id": reason }
            effectiveDate:
              type: string
              format: date-time
              description: >
                Date and time when the unenrollment becomes effective (ISO 8601 UTC).
                May be in the future for scheduled unenrollment.
              example: "2024-11-20T15:00:00Z"
              x-jsonld: { "@id": effectiveDate }
            revokeAllConsents:
              type: boolean
              description: >
                Boolean indicating whether all associated consents should be revoked during unenrollment.
                If true, all consent credentials associated with this enrollment will be revoked.
              example: true
              x-jsonld: { "@id": revokeAllConsents }
            status:
              type: string
              enum: [CANCELLED, PENDING]
              description: >
                Unenrollment status. CANCELLED when processed, PENDING when scheduled for future.
                Only present in on_update response.
              example: "CANCELLED"
              x-jsonld: { "@id": status }
            cancelledAt:
              type: string
              format: date-time
              description: >
                Timestamp when the enrollment was cancelled (ISO 8601 UTC).
                Only present in on_update response.
              example: "2024-11-20T15:00:05Z"
              x-jsonld: { "@id": cancelledAt }
            enrollmentCredentialStatus:
              type: object
              description: >
                Status information for the enrollment credential after revocation.
                Contains status list details for verification.
                Only present in on_update response.
              x-jsonld: { "@id": enrollmentCredentialStatus }
              additionalProperties: false
              properties:
                statusListUrl:
                  type: string
                  format: uri
                  description: URL of the status list for the enrollment credential.
                  example: "https://vpp-program-owner.example.com/status/enrollment-list"
                  x-jsonld: { "@id": statusListUrl }
                statusListIndex:
                  type: string
                  description: Index in the status list for the enrollment credential.
                  example: "12345"
                  x-jsonld: { "@id": statusListIndex }
                revoked:
                  type: boolean
                  description: Whether the enrollment credential has been revoked.
                  example: true
                  x-jsonld: { "@id": revoked }
            consentsRevoked:
              type: array
              description: >
                Array of consent credentials that were revoked as part of unenrollment.
                Only present in on_update response when revokeAllConsents was true.
              items:
                type: object
                additionalProperties: false
                properties:
                  consentCredentialId:
                    type: string
                    format: uri
                    description: Identifier of the revoked consent credential.
                    example: "https://vpp-program-owner.example.com/credentials/vc:consent:consumer-001"
                    x-jsonld: { "@id": consentCredentialId }
                  statusListUrl:
                    type: string
                    format: uri
                    description: URL of the status list for this consent credential.
                    example: "https://vpp-program-owner.example.com/status/consent-list"
                    x-jsonld: { "@id": statusListUrl }
                  statusListIndex:
                    type: string
                    description: Index in the status list for this consent credential.
                    example: "94567"
                    x-jsonld: { "@id": statusListIndex }
                  revoked:
                    type: boolean
                    description: Whether this consent credential has been revoked.
                    example: true
                    x-jsonld: { "@id": revoked }
              x-jsonld: { "@id": consentsRevoked }
            message:
              type: string
              description: >
                Human-readable message about the unenrollment status.
                Only present in on_update response.
              example: "Enrollment and all associated consents have been revoked."
              x-jsonld: { "@id": message }

        # Used in orderAttributes (on_confirm response)
        enrollmentId:
          type: string
          description: >
            Unique identifier for the enrollment. Assigned by BPP upon enrollment confirmation.
            Used for tracking, audit, and enrollment management.
          example: "enrollment-consumer-001"
          x-jsonld: { "@id": enrollmentId }

        programId:
          type: string
          description: >
            Identifier of the digital energy program. Matches the program ID from the init request.
          example: "program-flex-demand-response-001"
          x-jsonld: { "@id": programId }

        status:
          type: string
          enum: [ACTIVE, PENDING, CANCELLED, SUSPENDED]
          description: >
            Enrollment status. ACTIVE when enrollment is active, PENDING when awaiting activation,
            CANCELLED when unenrolled, SUSPENDED when temporarily suspended.
          example: "ACTIVE"
          x-jsonld: { "@id": status }

        enrolledAt:
          type: string
          format: date-time
          description: >
            Timestamp when enrollment was confirmed and logged by BPP (ISO 8601 UTC).
            May differ from startDate if enrollment is scheduled for future activation.
          example: "2024-10-15T10:35:05Z"
          x-jsonld: { "@id": enrolledAt }

        credential:
          type: object
          description: >
            Signed enrollment credential issued by BPP. Contains W3C Verifiable Credential (https://www.w3.org/TR/vc-data-model-2.0/) proving enrollment.
            Returned in on_confirm response.
          x-jsonld: { "@id": credential }
          allOf:
            - $ref: '#/components/schemas/VerifiableCredential'

        loggedAt:
          type: string
          format: date-time
          description: >
            Timestamp when enrollment was logged in BPP's audit system (ISO 8601 UTC).
            Used for audit trail and compliance.
          example: "2024-10-15T10:35:05Z"
          x-jsonld: { "@id": loggedAt }

        logReference:
          type: string
          description: >
            Reference identifier for the enrollment log entry.
            Used for audit trail, record keeping, and log retrieval.
          example: "log-enrollment-consumer-001"
          x-jsonld: { "@id": logReference }

    ########################################################################
    # VerifiableCredential (W3C VC Data Model v2.0)
    ########################################################################
    VerifiableCredential:
      type: object
      additionalProperties: false
      description: >
        Represents a W3C Verifiable Credential (https://www.w3.org/TR/vc-data-model-2.0/) used in enrollment flow.
        This is a wrapper/reference object that contains the credential data (as JWT or JSON-LD), metadata, and URLs.
        The actual credential follows W3C VC Data Model v2.0 structure. Can be a meter ownership credential,
        program eligibility credential, DER certification credential, or program enrollment credential.
      x-jsonld:
        "@type": "vc:VerifiableCredential"
      properties:
        credentialId:
          type: string
          description: >
            Unique identifier for the credential. Used to reference credentials
            in verification and conflict checking.
          example: "vc-meter-ownership-001"
          x-jsonld: { "@id": credentialId }

        type:
          type: string
          enum: [MeterOwnershipCredential, ProgramEligibilityCredential, DERCertificationCredential, ProgramEnrollmentCredential]
          description: >
            Credential type as per W3C VC Data Model v2.0. The credential must include 'VerifiableCredential' 
            in its type array plus one of these specific types. MeterOwnershipCredential proves meter ownership,
            ProgramEligibilityCredential proves eligibility, DERCertificationCredential
            proves DER certification, ProgramEnrollmentCredential represents an enrollment.
          example: "MeterOwnershipCredential"
          x-jsonld: { "@id": "vc:type" }

        format:
          type: string
          enum: [VC-JWT, VC-JSON-LD]
          description: >
            Credential format as per W3C VC Data Model v2.0. VC-JWT for JWT-encoded credentials,
            VC-JSON-LD for JSON-LD encoded credentials. The credentialData field contains the
            encoded credential that must conform to W3C VC structure when decoded.
          example: "VC-JWT"
          x-jsonld: { "@id": format }

        credentialData:
          type: string
          description: >
            The credential data itself, typically a JWT or JSON-LD string
            containing the W3C Verifiable Credential (https://www.w3.org/TR/vc-data-model-2.0/).
            Contains the full credential including signature/proof. When decoded, must conform
            to W3C VC Data Model v2.0 structure with @context, type, credentialSubject, issuer, etc.
          example: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
          x-jsonld: { "@id": credentialData }

        credentialUrl:
          type: string
          format: uri
          description: >
            URL where the credential can be accessed or retrieved.
            Used for enrollment credentials returned in on_confirm response.
            Optional for credentials in init request.
          example: "https://vpp-program-owner.example.com/credentials/vc:enrollment:consumer-001"
          x-jsonld: { "@id": credentialUrl }

        verificationUrl:
          type: string
          format: uri
          description: >
            URL for verifying the credential. Used for third-party verification
            of enrollment credentials. Optional for credentials in init request.
          example: "https://vpp-program-owner.example.com/verify/vc:enrollment:consumer-001"
          x-jsonld: { "@id": verificationUrl }

        issuedAt:
          type: string
          format: date-time
          description: >
            Timestamp when the credential was issued (ISO 8601 UTC).
            Maps to W3C VC issuanceDate property. Used for enrollment credentials in on_confirm response.
          example: "2024-10-15T10:35:05Z"
          x-jsonld: { "@id": "vc:issuanceDate" }

        expiresAt:
          type: string
          format: date-time
          nullable: true
          description: >
            Timestamp when the credential expires (ISO 8601 UTC).
            Maps to W3C VC expirationDate property. May be null for non-expiring credentials.
          example: "2025-10-15T10:35:05Z"
          x-jsonld: { "@id": "vc:expirationDate" }

        derId:
          type: string
          description: >
            DER identifier associated with a DER certification credential.
            Links the credential to a specific DER. Only present for
            DERCertificationCredential type.
          example: "der-solar-001"
          x-jsonld: { "@id": derId }

    ########################################################################
    # VerifiedCredential
    ########################################################################
    VerifiedCredential:
      type: object
      additionalProperties: false
      description: >
        Details of a credential that has been verified by the BPP.
        Returned in credentialVerification.verifiedCredentials array.
      x-jsonld:
        "@type": VerifiedCredential
      properties:
        credentialId:
          type: string
          description: >
            Identifier of the credential that was verified.
            Matches the credentialId from the init request.
          example: "vc-meter-ownership-001"
          x-jsonld: { "@id": credentialId }

        status:
          type: string
          enum: [VERIFIED, FAILED]
          description: >
            Verification status for this specific credential.
            VERIFIED if credential is valid, FAILED if invalid or expired.
          example: "VERIFIED"
          x-jsonld: { "@id": status }

        verifiedAt:
          type: string
          format: date-time
          description: >
            Timestamp when the credential was verified by BPP (ISO 8601 UTC).
          example: "2024-10-15T10:30:05Z"
          x-jsonld: { "@id": verifiedAt }

    ########################################################################
    # ConflictingEnrollment
    ########################################################################
    ConflictingEnrollment:
      type: object
      additionalProperties: false
      description: >
        Details of a conflicting enrollment that prevents the requested
        enrollment from proceeding. Returned in conflictCheck.conflictingEnrollments array.
      x-jsonld:
        "@type": ConflictingEnrollment
      properties:
        enrollmentId:
          type: string
          description: >
            Identifier of the conflicting enrollment.
            Used to reference the existing enrollment causing the conflict.
          example: "enrollment-existing-001"
          x-jsonld: { "@id": enrollmentId }

        programId:
          type: string
          description: >
            Program identifier of the conflicting enrollment.
            Identifies which program the meter/DER is already enrolled in.
          example: "program-flex-other-001"
          x-jsonld: { "@id": programId }

        conflictReason:
          type: string
          description: >
            Human-readable description of why the conflict exists.
            Explains the nature of the conflict (e.g., meter already enrolled,
            overlapping dates, etc.).
          example: "Meter umid-001 is already enrolled in program-flex-other-001 from 2024-09-01 to 2025-09-01"
          x-jsonld: { "@id": conflictReason }

        conflictType:
          type: string
          enum: [METER_ALREADY_ENROLLED, DER_ALREADY_ENROLLED, PROGRAM_CONFLICT, DATE_OVERLAP]
          description: >
            Type of conflict. METER_ALREADY_ENROLLED if meter is enrolled,
            DER_ALREADY_ENROLLED if DER is enrolled, PROGRAM_CONFLICT if program
            doesn't allow multiple enrollments, DATE_OVERLAP if dates overlap.
          example: "METER_ALREADY_ENROLLED"
          x-jsonld: { "@id": conflictType }

    ########################################################################
    # UserAuth - REQUEST (BAP → BPP)
    ########################################################################
    UserAuthRequest:
      description: >
        User authentication request - sent by BAP to BPP in init/confirm requests.
        Supports OTP-based or OAuth2/OIDC token-based authentication.
      oneOf:
        - $ref: '#/components/schemas/OtpAuthRequest'
        - $ref: '#/components/schemas/OAuth2AuthRequest'
      discriminator:
        propertyName: authMethod
        mapping:
          OTP: '#/components/schemas/OtpAuthRequest'
          OAUTH2: '#/components/schemas/OAuth2AuthRequest'
          OIDC: '#/components/schemas/OAuth2AuthRequest'

    ########################################################################
    # UserAuth - RESPONSE (BPP → BAP)
    ########################################################################
    UserAuthResponse:
      description: >
        User authentication response - returned by BPP to BAP in on_init/on_confirm responses.
        Contains verification results and extracted user identity.
      oneOf:
        - $ref: '#/components/schemas/OtpAuthResponse'
        - $ref: '#/components/schemas/OAuth2AuthResponse'
      discriminator:
        propertyName: authMethod
        mapping:
          OTP: '#/components/schemas/OtpAuthResponse'
          OAUTH2: '#/components/schemas/OAuth2AuthResponse'
          OIDC: '#/components/schemas/OAuth2AuthResponse'

    ########################################################################
    # OtpAuthRequest (BAP → BPP)
    ########################################################################
    OtpAuthRequest:
      type: object
      additionalProperties: false
      required:
        - authMethod
        - mobile
      description: >
        OTP authentication request from BAP.
        - Init request: Send mobile number to initiate OTP
        - Confirm request: Send mobile + nguid + otp for verification
      x-jsonld:
        "@type": OtpAuthRequest
      properties:
        authMethod:
          type: string
          enum: [OTP]
          description: Authentication method. Must be "OTP".
          example: "OTP"
          x-jsonld: { "@id": authMethod }

        mobile:
          type: string
          description: Mobile phone number in E.164 format. Required.
          example: "+919999999999"
          x-jsonld: { "@id": mobile }

        otp:
          type: string
          description: >
            One-time password entered by user.
            Required in confirm request (after user receives OTP via SMS).
          example: "123456"
          x-jsonld: { "@id": otp }

        nguid:
          type: string
          description: >
            Session token received from on_init response.
            Required in confirm request along with otp.
          example: "LQUejkRbBL9nJGQiqbComfQ242AHnbG3hnwWdHJut59jqmdJygnVHoiyDcnAUrKm"
          x-jsonld: { "@id": nguid }

        utilityCustomerId:
          type: string
          description: >
            Customer account identifier assigned by the utility/DISCOM.
            Optional - BAP may include if known from prior interactions.
          example: "CUST-123456"
          x-jsonld: { "@id": utilityCustomerId }

        userType:
          type: string
          description: >
            Type of user.
            CONSUMER for consumer, PRODUCER for producer, PROSUMER for prosumer.
          example: "CONSUMER"
          x-jsonld: { "@id": userType }

    ########################################################################
    # OtpAuthResponse (BPP → BAP)
    ########################################################################
    OtpAuthResponse:
      type: object
      additionalProperties: false
      required:
        - authMethod
      description: >
        OTP authentication response from BPP.
        - On_init response: Returns nguid and message ("OTP sent")
        - On_confirm response: Returns verification result
      x-jsonld:
        "@type": OtpAuthResponse
      properties:
        authMethod:
          type: string
          enum: [OTP]
          description: Authentication method. Always "OTP".
          example: "OTP"
          x-jsonld: { "@id": authMethod }

        nguid:
          type: string
          description: >
            Session token generated by BPP. Returned in on_init response.
            BAP must include this in confirm request.
          example: "LQUejkRbBL9nJGQiqbComfQ242AHnbG3hnwWdHJut59jqmdJygnVHoiyDcnAUrKm"
          x-jsonld: { "@id": nguid }

        message:
          type: string
          description: >
            Human-readable status message.
            e.g., "OTP sent to +91XXXXXX9999" or "Verification successful".
          example: "OTP sent to +91XXXXXX9999. Valid for 5 minutes."
          x-jsonld: { "@id": message }

        expiresAt:
          type: string
          format: date-time
          description: When OTP/nguid expires (ISO 8601 UTC).
          example: "2024-10-15T10:35:00Z"
          x-jsonld: { "@id": expiresAt }

        verified:
          type: boolean
          description: Whether OTP verification succeeded. Present in on_confirm.
          example: true
          x-jsonld: { "@id": verified }

        verifiedAt:
          type: string
          format: date-time
          description: When OTP was verified (ISO 8601 UTC).
          example: "2024-10-15T10:35:05Z"
          x-jsonld: { "@id": verifiedAt }

        utilityId:
          type: string
          description: >
            Utility/DISCOM identifier returned by IdP after authentication.
            Identifies which utility the authenticated user's account belongs to.
          example: "utility-example-001"
          x-jsonld: { "@id": utilityId }

        utilityCustomerId:
          type: string
          description: >
            Customer account identifier assigned by the utility/DISCOM.
            Returned by IdP to link the authenticated user to their utility billing account.
          example: "CUST-123456"
          x-jsonld: { "@id": utilityCustomerId }

    ########################################################################
    # OAuth2AuthRequest (BAP → BPP)
    ########################################################################
    OAuth2AuthRequest:
      type: object
      additionalProperties: false
      required:
        - authMethod
        - accessToken
      description: >
        OAuth2/OIDC authentication request from BAP.
        Contains JWT tokens for BPP to validate. BPP extracts claims from token.
      x-jsonld:
        "@type": OAuth2AuthRequest
      properties:
        authMethod:
          type: string
          enum: [OAUTH2, OIDC]
          description: >
            Authentication method.
            "OAUTH2" for access token only, "OIDC" for access + ID token.
          example: "OIDC"
          x-jsonld: { "@id": authMethod }

        accessToken:
          type: string
          description: OAuth2 access token (bearer token). Required.
          example: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
          x-jsonld: { "@id": accessToken }

        idToken:
          type: string
          description: >
            OIDC ID token (JWT with user claims).
            Required when authMethod is "OIDC".
          example: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
          x-jsonld: { "@id": idToken }

        refreshToken:
          type: string
          description: >
            OAuth2 refresh token. Optional - for long-running flows
            where token might expire mid-transaction.
          example: "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4..."
          x-jsonld: { "@id": refreshToken }

    ########################################################################
    # OAuth2AuthResponse (BPP → BAP)
    ########################################################################
    OAuth2AuthResponse:
      type: object
      additionalProperties: false
      required:
        - authMethod
      description: >
        OAuth2/OIDC authentication response from BPP.
        Contains verification results and extracted user identity from token.
      x-jsonld:
        "@type": OAuth2AuthResponse
      properties:
        authMethod:
          type: string
          enum: [OAUTH2, OIDC]
          description: Authentication method that was used.
          example: "OIDC"
          x-jsonld: { "@id": authMethod }

        verified:
          type: boolean
          description: Whether token verification succeeded.
          example: true
          x-jsonld: { "@id": verified }

        verifiedAt:
          type: string
          format: date-time
          description: When token was verified (ISO 8601 UTC).
          example: "2024-10-15T10:35:05Z"
          x-jsonld: { "@id": verifiedAt }

        subject:
          type: string
          description: >
            User identifier extracted from token "sub" claim.
          example: "user-12345"
          x-jsonld: { "@id": subject }

        issuer:
          type: string
          format: uri
          description: >
            OIDC issuer URL extracted from token "iss" claim.
          example: "https://accounts.google.com"
          x-jsonld: { "@id": issuer }

        scope:
          type: string
          description: >
            Scopes granted to the token (extracted from token or introspection).
          example: "openid profile email meter:read"
          x-jsonld: { "@id": scope }

        expiresAt:
          type: string
          format: date-time
          description: When the access token expires (from "exp" claim).
          example: "2024-10-15T11:35:00Z"
          x-jsonld: { "@id": expiresAt }

        message:
          type: string
          description: Human-readable verification status message.
          example: "Token verified successfully"
          x-jsonld: { "@id": message }

    ########################################################################
    # MeterEnrollment (Meter details for enrollment)
    ########################################################################
    MeterEnrollment:
      type: object
      additionalProperties: false
      required:
        - meterId
      description: >
        Meter details for enrollment in an energy program.
        Contains meter identifier (UMID) and optional utility information.
        Used in the meters array within orderAttributes during confirm request.
        At least one meter must be specified for enrollment to be confirmed.
      x-jsonld:
        "@type": MeterEnrollment
      properties:
        meterId:
          type: string
          description: >
            Unique Meter Identifier (UMID) for the meter to be enrolled.
            This is the primary identifier used by the utility/DISCOM.
          example: "umid-001"
          x-jsonld: { "@id": meterId }

        meterNumber:
          type: string
          description: >
            Physical meter number as displayed on the meter device.
            May differ from meterId which is the utility's internal identifier.
          example: "MTR-123456"
          x-jsonld: { "@id": meterNumber }

        utilityId:
          type: string
          description: >
            Identifier of the utility/DISCOM that owns or manages the meter.
          example: "utility-tpddl-001"
          x-jsonld: { "@id": utilityId }

        connectionType:
          type: string
          enum: [residential, commercial, industrial, agricultural]
          description: >
            Type of electricity connection for this meter.
          example: "residential"
          x-jsonld: { "@id": connectionType }

        sanctionedLoad:
          type: number
          minimum: 0
          description: >
            Sanctioned load capacity in kilowatts (kW) for this meter connection.
          example: 5.0
          x-jsonld: { "@id": sanctionedLoad }

