Skip to content

feat: implement validation and invalidation#118

Merged
Agrendalath merged 13 commits intomainfrom
agrendalath/bb-10170-validation
Feb 13, 2026
Merged

feat: implement validation and invalidation#118
Agrendalath merged 13 commits intomainfrom
agrendalath/bb-10170-validation

Conversation

@Agrendalath
Copy link
Member

@Agrendalath Agrendalath commented Nov 3, 2025

Added

  • Credential validation and invalidation system with INVALIDATED status.
  • verify_uuid field on credentials — a separate UUID used for third-party verification, distinct from the primary key.
  • invalidated_at timestamp and invalidation_reason fields on the Credential model.
  • learning_context_name cached field on credentials for use in validation display.
  • Public API endpoint (/api/learning_credentials/v1/metadata/<uuid>/) to retrieve credential metadata by verification UUID.
  • "Reissue credential" admin action that invalidates the current credential and generates a new one.
  • {verify_uuid} placeholder support in PDF text elements.
  • Admin test suite (test_admin.py) and included it in test coverage.

Changed

  • Replaced user_id (IntegerField) with a user ForeignKey to the User model.
  • Added configuration ForeignKey on Credential linking to CredentialConfiguration, replacing credential_type and learning_context_key lookups.
  • Simplified generate_pdf_credential() signature to accept a Credential object instead of separate parameters.
  • Changed the PDF output directory from hardcoded external_certificates/ to the configurable LEARNING_CREDENTIALS_OUTPUT_DIR setting.
  • Credential issue date on PDFs now uses the credential's creation date instead of the current time.
  • get_localized_credential_date() now accepts an explicit datetime parameter.
  • Disabled add and delete permissions for credentials in the Django admin.

@Agrendalath Agrendalath changed the base branch from main to agrendalath/bb-9902-rest-api November 3, 2025 14:06
@Agrendalath Agrendalath force-pushed the agrendalath/bb-10170-validation branch from fb44a7c to 0e6c112 Compare November 5, 2025 21:52
This was linked to issues Nov 24, 2025
@Agrendalath Agrendalath force-pushed the agrendalath/bb-9902-rest-api branch 2 times, most recently from 1d9c576 to a483669 Compare December 15, 2025 20:23
Base automatically changed from agrendalath/bb-9902-rest-api to main December 15, 2025 21:26
@Agrendalath Agrendalath force-pushed the agrendalath/bb-10170-validation branch from 184aefd to 6c6bded Compare December 15, 2025 22:09
@Agrendalath Agrendalath force-pushed the agrendalath/bb-10170-validation branch from 6c6bded to 65de928 Compare January 29, 2026 00:11
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces credential verification and invalidation capabilities, alongside a schema refactor to normalize credential data and add richer metadata.

Changes:

  • Add a public API endpoint and UI page to verify credentials by a dedicated verification UUID, exposing limited, read-only metadata.
  • Refactor the Credential model to reference User and CredentialConfiguration via FKs, add verify_uuid, learning_context_name, and invalidation fields, and update generators and admin to support invalidation and reissue flows.
  • Extend and adjust the test suite (models, generators, admin, views) plus migrations, versioning, and documentation to cover the new behavior.

Reviewed changes

Copilot reviewed 21 out of 23 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
uv.lock Bumps the locked version of the local learning-credentials package to 0.5.0rc3 to match the code changes.
pyproject.toml Updates the project version to 0.5.0rc3 for the new release containing verification and invalidation features.
CHANGELOG.rst Adds a 0.5.0 section describing the new verification endpoint/UI and invalidation option.
learning_credentials/models.py Refactors Credential to use user FK and configuration FK, adds verify_uuid, learning_context_name, invalidated_at, and invalidation_reason, implements automatic invalidation logic and a reissue() method, and adjusts CredentialConfiguration.generate_credential_for_user to work with the new schema and generator signature.
learning_credentials/migrations/0008_validation.py Introduces verification and invalidation fields on Credential, backfills verify_uuid and learning_context_name, and removes the old unique_together constraint.
learning_credentials/migrations/0009_credential_user_fk.py Migrates from an integer user_id on Credential to a proper user FK to AUTH_USER_MODEL.
learning_credentials/migrations/0010_credential_configuration_fk.py Adds a FK from Credential to CredentialConfiguration and removes the redundant learning_context_key and credential_type fields from Credential.
learning_credentials/migrations/0001_squashed_0010.py Provides a squashed initial migration that encapsulates the full current schema including Credential, CredentialConfiguration, assets, and new verification/invalidation fields for fresh installs.
learning_credentials/generators.py Updates PDF generation to operate on a Credential instance, uses learning_context_name and verify_uuid, parameterizes the localized date, adds _get_credential_paths and _invalidate_credential helpers, and supports invalidation by archiving PDFs and clearing URLs.
learning_credentials/compat.py Changes get_localized_credential_date to accept a datetime argument and format that timestamp in the configured timezone.
learning_credentials/api/v1/serializers.py Adds CredentialSerializer exposing user_full_name, created, learning_context_name, status, and invalidation_reason for verification responses.
learning_credentials/api/v1/views.py Extends the API with CredentialMetadataView to fetch credential metadata by verify_uuid, returning 404 on missing credentials.
learning_credentials/api/v1/urls.py Wires the new metadata endpoint at v1/metadata/<uuid:uuid>/ under the existing API namespace.
learning_credentials/urls.py Adds a TemplateView-based route for the credential verification page at /learning_credentials/verify/.
learning_credentials/templates/learning_credentials/verify.html Implements a simple UI form that accepts a credential ID, calls the metadata API via fetch, and renders returned metadata in a details table.
learning_credentials/admin.py Enhances admin for CredentialConfiguration and Credential (docstring-based help, read-only key fields, generate/reissue actions, disabled add/delete for credentials, and customized URL display and form behavior).
tests/test_models.py Updates model tests to the new schema, adds coverage for invalidation and reissue logic, configuration-based generation using configuration and learning_context_name, and filtering logic using the new relationships.
tests/test_generators.py Aligns generator tests with the new generate_pdf_credential signature, adds coverage for verify_uuid placeholders, output paths, invalidation/archiving behavior, and S3 ACL handling.
tests/test_views.py Extends API tests to cover the new CredentialMetadataView, ensuring correct responses for valid, missing, and invalidated credentials.
tests/test_admin.py Adds comprehensive tests for admin forms and actions, including docstring-based options help, configuration inline behavior, credential admin permissions, URL display, validation error handling, and the reissue action.
tests/conftest.py Introduces reusable fixtures for mock retrieval/generation functions, mock credential types/configs, credential instances, email patching, and a temporary media root used by generator and asset tests.
.gitignore Removes the now-obsolete external_certificates/ ignore, since credential PDFs are stored under the default storage path (learning_credentials/) instead.
.coveragerc Stops excluding admin.py from coverage so the new admin tests are counted.
Comments suppressed due to low confidence (1)

learning_credentials/generators.py:395

  • The placeholder list in this docstring is now out of date: _write_text_on_template and the options plumbing also support {verify_uuid} (via the placeholders dict), but the documentation here still only mentions {name}, {context_name}, and {issue_date}. To avoid confusing integrators configuring custom text_elements, please update this section to include {verify_uuid} in the list of available placeholders.
    Options:

      - template (required): The slug of the PDF template asset.
      - template_multiline: Alternative template for multiline context names (when using '\n').
      - defaults: Global defaults for all text elements.
          - font: Font name (asset slug). Default: Helvetica.
          - color: Hex color code. Default: #000.
          - size: Font size in points. Default: 12.
          - char_space: Character spacing. Default: 0.
          - uppercase: Convert text to uppercase. Default: false.
          - line_height: Line height multiplier for multiline text. Default: 1.1.
      - text_elements: Configuration for text elements. Standard elements (name, context, date) have
          defaults and render automatically. Set to false to hide.
          Custom elements require 'text' and 'y' properties.
          Element properties:
          - text: Text content with {placeholder} substitution. Available: {name}, {context_name}, {issue_date}.
          - y: Vertical position (PDF coordinates from bottom).
          - size: Font size (inherited from defaults.size).
          - font: Font name (inherited from defaults.font).
          - color: Hex color (inherited from defaults.color).
          - char_space: Character spacing (inherited from defaults.char_space).
          - uppercase: Convert text to uppercase (inherited from defaults.uppercase).
          - line_height: Line height multiplier for multiline text (inherited from defaults.line_height).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Agrendalath Agrendalath marked this pull request as ready for review February 12, 2026 23:55
@Agrendalath Agrendalath force-pushed the agrendalath/bb-10170-validation branch from be7cdce to 7b486e5 Compare February 13, 2026 16:33
@Agrendalath Agrendalath merged commit 95ff874 into main Feb 13, 2026
11 checks passed
@Agrendalath Agrendalath deleted the agrendalath/bb-10170-validation branch February 13, 2026 17:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Validation Certificate invalidation

2 participants