Overview
CCDigital integrates with Hyperledger Fabric to provide immutable document traceability and audit logging. The blockchain layer operates alongside the MySQL database, recording document metadata and access events on-chain. Architecture:- MySQL: Primary transactional data store
- Fabric: Audit trail and document registry
- Node.js Scripts: CLI interface to Fabric chaincode
Blockchain functions as an additional trust layer, not the primary data source. All operations first complete in MySQL, then optionally sync to Fabric.
Service Components
FabricLedgerCliService
Package:co.edu.unbosque.ccdigital.service
Purpose: Query documents directly from Fabric ledger
Key Features:
- Lists documents for a person from chaincode
- Executes
list-docs.jsNode.js script - Parses JSON responses into typed DTOs
- Does NOT query MySQL database
FabricAuditCliService
Package:co.edu.unbosque.ccdigital.service
Purpose: Record and query audit events on Fabric
Key Features:
- Records access events (view, download, approval)
- Lists audit events per person or globally
- Executes
record-access-event.jsandlist-access-events.js - Returns typed
FabricAuditEventViewobjects
ExternalToolsService
Package:co.edu.unbosque.ccdigital.service
Purpose: Generic command execution service for external tools
Key Features:
- Executes Node.js and Python scripts
- Captures stdout/stderr in parallel
- Timeout management (default 180 seconds)
- Structured result with exit code and timestamps
BlockchainTraceDetailService
Package:co.edu.unbosque.ccdigital.service
Purpose: Detailed blockchain transaction inspection for admin reports
Configuration
Fabric Scripts (Node.js)
FABRIC_WORKDIRFABRIC_NODE_BINFABRIC_LIST_DOCS_SCRIPTFABRIC_SYNC_ALL_SCRIPTFABRIC_SYNC_PERSON_SCRIPTEXTERNAL_TOOLS_TIMEOUT_SECONDS
FabricLedgerCliService Methods
listDocsRaw(String idType, String idNumber)
listDocsRaw(String idType, String idNumber)
Executes Parameters:
list-docs.js and returns raw stdout.Command Format:idType- ID type (CC,TI, etc.)idNumber- ID number
String - Raw stdout from scriptThrows: RuntimeException if exit code != 0Example:listDocsView(String idType, String idNumber)
listDocsView(String idType, String idNumber)
Executes
list-docs.js and returns typed document list.Parameters:idType- ID typeidNumber- ID number
List<FabricDocView> with fields:docId- Document ID on ledgertitle- Document titleissuingEntity- Issuer namecreatedAt- Creation timestampsizeBytes- File sizefilePath- Storage path
- Extracts first JSON array from stdout (from
[to]) - Maps JSON properties to
FabricDocViewrecord - Handles mixed output (logs + JSON)
findDocById(String idType, String idNumber, String docId)
findDocById(String idType, String idNumber, String docId)
Finds a specific document by ID from Fabric.Parameters:
idType- ID typeidNumber- ID numberdocId- Document ID to find
Optional<FabricDocView>Usage:FabricAuditCliService Methods
recordEvent(AuditCommand command)
recordEvent(AuditCommand command)
Records an audit event on Fabric (write transaction).Command Structure:Executes:Returns:
FabricAuditEventView - Event record with txIdArgument Handling:- Empty values are replaced with
"-" - All strings are trimmed
listEventsForPerson(String idType, String idNumber)
listEventsForPerson(String idType, String idNumber)
Lists all audit events for a specific person.Command:Returns:
List<FabricAuditEventView>Example:listAllEvents()
listAllEvents()
Lists all audit events on the ledger (global view).Command:Returns:
List<FabricAuditEventView>Usage:ExternalToolsService Methods
runFabricSyncAll()
runFabricSyncAll()
Synchronizes all database records to Fabric ledger.Command:Returns:
ExecResult with:exitCode- 0 = successstdout- Command outputstderr- Error outputstartedAt- Execution start timestampfinishedAt- Execution end timestampcommand- Executed command tokens
runFabricSyncPerson(String idType, String idNumber)
runFabricSyncPerson(String idType, String idNumber)
Synchronizes documents for a specific person.Command:Parameters:
idType- ID typeidNumber- ID number
ExecResultExample:exec(List<String> command, String workdir, Map<String, String> extraEnv)
exec(List<String> command, String workdir, Map<String, String> extraEnv)
Generic command execution with full control.Parameters:
command- Command tokens (e.g.,["node", "script.js", "arg1"])workdir- Working directory (can be empty)extraEnv- Additional environment variables
ExecResultFeatures:- Parallel stdout/stderr capture (prevents deadlock)
- Configurable timeout (default 180s)
- Exit code 124 for timeout
- Exit code 2 for configuration errors
Synchronization Workflows
Global Sync (Admin Dashboard)
- Admin clicks “Sync All to Fabric”
ExternalToolsService.runFabricSyncAll()called- Script reads all documents from MySQL
- For each document:
- Checks if exists on ledger
- Creates or updates record
- Returns summary (created/updated/failed)
Per-Person Sync
- Admin selects person
- Clicks “Sync Person to Fabric”
ExternalToolsService.runFabricSyncPerson()called- Script filters by
idTypeandidNumber - Syncs only that person’s documents
FabricAuditEventView Structure
ExecResult Structure
Error Handling
Script Execution Errors
| Exit Code | Meaning | Action |
|---|---|---|
| 0 | Success | Process output |
| 1 | Script error | Check stderr for details |
| 2 | Configuration error | Verify properties |
| 124 | Timeout | Increase timeout or optimize script |
Configuration Validation
JSON Extraction
Both services handle mixed output (logs + JSON): Array Extraction:Best Practices
- Always validate configuration before executing scripts
- Handle timeouts gracefully - blockchain operations can be slow
- Log both stdout and stderr for troubleshooting
- Use controlled error messages (avoid exposing internal paths)
- Sanitize arguments - replace empty values with
"-" - Parse JSON defensively - extract arrays/objects from mixed output
Related Services
- File Storage Service - Document file management (FileStorageService:154)
- Identity Services - User access state sync (UserAccessGovernanceService:111)
- AdminReportService - Blockchain trace aggregation for reports
