Skip to main content

Overview

The Issuer Module enables authorized institutional entities (government agencies, banks, universities, etc.) to upload official documents for citizens and create access requests for approved documents. All uploads undergo mandatory review before becoming accessible.

Person Search

Find citizens by ID type and number

Document Upload

Upload PDF documents with metadata and validation

Access Requests

Create requests to access approved documents

Document Viewing

View and download authorized documents

Security & Authentication

Role Required: ROLE_ISSUER Access Path: /issuer/** and /login/issuer Issuers are represented by the IssuingEntity entity and authenticated via IssuerPrincipal. The authenticated issuer’s ID is retrieved from the security context for authorization checks. Controller: IssuerController (src/main/java/co/edu/unbosque/ccdigital/controller/IssuerController.java:67)

Key Features

Issuers must first locate the citizen before uploading documents.
1

Access Issuer Home

Navigate to the issuer dashboard at /issuerEndpoint: GET /issuerController: IssuerController (src/main/java/co/edu/unbosque/ccdigital/controller/IssuerController.java:91)
2

Search by Identification

Use the search form to find a person by:
  • ID Type (CC, TI, CE, etc.)
  • ID Number
Endpoint: POST /issuer/searchController: IssuerController (src/main/java/co/edu/unbosque/ccdigital/controller/IssuerController.java:132)
3

View Person Context

Upon successful search, the page reloads with:
  • Person details
  • Existing documents for that person
  • Allowed document types for your entity
  • Document upload form
The URL includes ?personId={id} parameter to maintain context.
If the person is not found, an error message is displayed. The person must be created by an administrator before documents can be uploaded.

Document Upload

Issuers can only upload document types allowed for their entity as defined in entity_document_definitions table. Endpoint: POST /issuer/upload Controller: IssuerController (src/main/java/co/edu/unbosque/ccdigital/controller/IssuerController.java:153) Service: PersonDocumentService#uploadFromIssuer

Upload Requirements

PDF Only: The issuer module enforces strict PDF validation:
  1. File extension must be .pdf
  2. MIME type must contain “pdf”
  3. File content must start with %PDF signature
Validation occurs at both controller (IssuerController.java:160) and service layers.

Upload Workflow

1

Select Person

Search and select the person to receive the document.
2

Choose Document Type

Select from allowed document definitions for your issuing entity.Service: DocumentDefinitionService#findAllowedByIssuer
3

Provide Metadata

Fill in document details:
  • Document type (from allowed list)
  • Status (typically PENDING for review)
  • Issue date
  • Expiry date (optional)
4

Upload PDF File

Select and upload the PDF document file.The file undergoes:
  • PDF format validation
  • SHA-256 hash calculation
  • Storage in person’s physical folder
  • Database record creation
5

Await Review

Document enters PENDING status and must be reviewed by an administrator before becoming accessible.Review Status Options:
  • PENDING - Awaiting administrative review
  • APPROVED - Available for access requests
  • REJECTED - Failed review

Form Data Structure

Form DTO: IssuerUploadForm
private Long personId;        // Target person
private Long documentId;      // Document definition ID
private String status;        // Review status
private LocalDate issueDate;  // Document issue date
private LocalDate expiryDate; // Optional expiry

Access Request Management

Issuers can create access requests for approved documents and view authorized documents.
Access request functionality is referenced in README.md section 3.2 with these endpoints:
  • GET /issuer/access-requests - List access requests
  • GET /issuer/access-requests/new - Create new request
  • GET /issuer/access-requests/{requestId}/documents/{personDocumentId}/view - View document
  • GET /issuer/access-requests/{requestId}/documents/{personDocumentId}/download - Download document

Creating Access Requests

Access requests allow issuers to formally request permission to view specific approved documents. Requirements:
  • Documents must be in APPROVED status
  • Request must specify which documents are needed
  • User must approve the request before access is granted
Data Model:
  • access_requests table stores request metadata
  • access_request_items table links specific documents to requests
  • Requests have a status workflow (pending → approved/rejected)

Viewing Approved Documents

Once an access request is approved by the end user:
  1. Request status changes to APROBADA
  2. Request must be within validity period
  3. Issuer can view and download the approved documents
  4. Access events are recorded for audit trail
Security:
  • Access is validated via signed URLs (SignedUrlService)
  • File paths are validated against allowed directories
  • Access events are logged to Fabric ledger

Endpoint Reference

HTTP MethodEndpointDescriptionController Line
GET/issuerIssuer dashboard homeIssuerController.java:91
POST/issuer/searchSearch person by IDIssuerController.java:132
POST/issuer/uploadUpload document for personIssuerController.java:153
GET/issuer/access-requestsList access requestsREADME.md:149
GET/issuer/access-requests/newCreate access request formREADME.md:150
GET/issuer/access-requests/{requestId}/documents/{personDocumentId}/viewView documentREADME.md:151
GET/issuer/access-requests/{requestId}/documents/{personDocumentId}/downloadDownload documentREADME.md:152

Data Model

Key Entities

IssuingEntity (entities table)
  • Represents the issuer organization
  • Links to entity users via entity_users table
  • Defines allowed document types via entity_document_definitions
Person (persons table)
  • Citizen identity record
  • Created by administrators
  • Links to documents via person_documents
PersonDocument (person_documents table)
  • Document metadata
  • Links to person and document definition
  • Tracks review status
  • References physical file via files table
AccessRequest (access_requests table)
  • Request for document access
  • Links to entity and person
  • Has approval workflow
AccessRequestItem (access_request_items table)
  • Links specific documents to requests
  • Enables granular access control

Database Procedures

The issuer module leverages stored procedures for complex operations:
  • sp_add_person_document - Atomic document creation
  • sp_upload_file_path - File metadata persistence
  • sp_upload_pdf_blob - Binary storage handling

Integration Points

PersonService

Provides person lookup and validation:
Optional<Person> findByIdTypeAndNumber(IdType idType, String idNumber)
Usage: Person search functionality (IssuerController.java:135)

PersonDocumentService

Handles document upload workflow:
void uploadFromIssuer(
    Long issuerId,
    Long personId, 
    Long documentId,
    String status,
    LocalDate issueDate,
    LocalDate expiryDate,
    MultipartFile file
)
Responsibilities:
  • Validates issuer permissions
  • Enforces PDF-only validation
  • Checks document definition authorization
  • Persists file and metadata
  • Sets initial review status

DocumentDefinitionService

Filters allowed document types per issuer:
List<DocumentDefinition> findAllowedByIssuer(Long issuerId)
Source: entity_document_definitions table

FileStorageService

Manages physical file operations:
  • Stores files in normalized folder structure
  • Calculates SHA-256 hashes
  • Validates file paths against security policies
  • Base path configured via CCDIGITAL_FS_BASE_PATH

PDF Validation Details

The issuer module implements three-layer PDF validation to ensure document integrity:

Layer 1: Controller Pre-Check

Location: IssuerController#isPdfUpload (IssuerController.java:192)
private boolean isPdfUpload(MultipartFile file) {
    // Check file existence
    // Validate .pdf extension
    // Validate MIME type contains "pdf"
}
Purpose: Fast rejection with user-friendly message before service invocation

Layer 2: Service Validation

Location: PersonDocumentService#uploadFromIssuer
  • Validates file extension
  • Checks MIME type
  • Verifies PDF signature (%PDF at file start)
  • Prevents non-PDF files from entering storage

Layer 3: Storage Integrity

Location: FileStorageService
  • Calculates SHA-256 hash for tamper detection
  • Stores hash in files table for verification
  • Validates file path security
All three validation layers must pass. Attempting to upload non-PDF files will result in rejection with the error message: “Solo se permite subir archivos PDF.”

Configuration

Key environment variables for the issuer module:
# Filesystem Storage
CCDIGITAL_FS_BASE_PATH=/path/to/document/storage

# Database
DB_URL=jdbc:mysql://host:port/database
DB_USERNAME=dbuser
DB_PASSWORD=dbpass

# Security
APP_SECURITY_SIGNED_URLS_SECRET=your-secret-key
APP_SECURITY_SIGNED_URLS_TTL_SECONDS=3600

Error Handling

Common Error Scenarios:
ErrorCauseResolution
”Persona no encontrada”Person doesn’t exist in systemContact admin to create person record
”Solo se permite subir archivos PDF”Non-PDF file upload attemptConvert document to PDF format
Invalid document typeDocument not allowed for issuerUse only allowed document definitions
Permission deniedIssuer not authorized for document typeContact admin to update permissions
File too largeExceeds upload size limitCompress PDF or split into multiple files

Best Practices

  1. Person Verification: Always verify person details before uploading documents
  2. Document Quality: Ensure PDFs are clean, readable, and properly formatted
  3. Metadata Accuracy: Double-check issue dates and expiry dates before submission
  4. Access Requests: Only request access to documents necessary for your business purpose
  5. Timely Review: Monitor review status and follow up on pending documents
  6. Data Privacy: Handle citizen documents according to data protection regulations

Workflow Example

1

Login as Issuer

Authenticate at /login/issuer with issuer credentials.
2

Search for Citizen

Use person search with ID type (e.g., CC) and ID number.
3

Upload Document

Select allowed document type, provide metadata, upload PDF file.Document enters PENDING review status.
4

Admin Reviews

Administrator reviews document in admin module and approves/rejects.
5

Create Access Request

Once approved, create access request for the document (if needed).
6

User Approves

End user reviews and approves the access request.
7

View Document

Access granted - view and download the document.Access event recorded to blockchain audit trail.

Build docs developers (and LLMs) love