@@ -1133,15 +1133,7 @@ impl CertificateContract {
11331133 }
11341134
11351135 // Perform substitution in description
1136- let mut description = params. description . clone ( ) ;
1137- for ( name, value) in field_values. iter ( ) {
1138- // Substitution logic note:
1139- // While full string replacement is expensive on-chain, we store the values
1140- // here to ensure the certificate remains fully audit-compliant and
1141- // substitution can be verified deterministically.
1142- let _ = ( name, value) ;
1143- }
1144-
1136+ let description = params. description . clone ( ) ;
11451137 storage:: set_template_values ( & env, & params. certificate_id , & field_values) ;
11461138
11471139 let anchor = generate_blockchain_anchor ( & env, & params. certificate_id ) ;
@@ -1183,7 +1175,13 @@ impl CertificateContract {
11831175 a. active_certificates += 1 ;
11841176 } ) ;
11851177
1186- record_audit ( & env, & params. certificate_id , AuditAction :: Executed , & admin, "Issued with template" ) ;
1178+ record_audit (
1179+ & env,
1180+ & params. certificate_id ,
1181+ AuditAction :: Executed ,
1182+ & admin,
1183+ "Issued with template" ,
1184+ ) ;
11871185
11881186 Ok ( params. certificate_id )
11891187 }
@@ -1199,6 +1197,13 @@ impl CertificateContract {
11991197 let template =
12001198 storage:: get_template ( & env, & template_id) . ok_or ( CertificateError :: TemplateNotFound ) ?;
12011199
1200+ // Validate required fields
1201+ for field in template. fields . iter ( ) {
1202+ if field. is_required && !field_values. contains_key ( field. field_name . clone ( ) ) {
1203+ return Err ( CertificateError :: MissingRequiredField ) ;
1204+ }
1205+ }
1206+
12021207 Ok ( Certificate {
12031208 certificate_id : BytesN :: from_array ( & env, & [ 0u8 ; 32 ] ) ,
12041209 course_id,
@@ -1397,28 +1402,24 @@ impl CertificateContract {
13971402 // 1. Expiry Check
13981403 if cert. expiry_date != 0 && env. ledger ( ) . timestamp ( ) > cert. expiry_date {
13991404 is_compliant = false ;
1400- violation_details = String :: from_str ( & env, "Certificate has expired; " ) ;
1405+ violation_details = String :: from_str ( & env, "Expired " ) ;
14011406 }
1402-
14031407 // 2. Status Check
1404- if cert. status != CertificateStatus :: Active {
1408+ else if cert. status != CertificateStatus :: Active {
14051409 is_compliant = false ;
1406- let status_msg = match cert. status {
1407- CertificateStatus :: Revoked => "Revoked" ,
1408- CertificateStatus :: Suspended => "Suspended" ,
1409- CertificateStatus :: Expired => "Expired" ,
1410- CertificateStatus :: Reissued => "Reissued" ,
1411- _ => "Inactive" ,
1410+ violation_details = match cert. status {
1411+ CertificateStatus :: Revoked => String :: from_str ( & env, "Status: Revoked" ) ,
1412+ CertificateStatus :: Suspended => String :: from_str ( & env, "Status: Suspended" ) ,
1413+ CertificateStatus :: Expired => String :: from_str ( & env, "Status: Expired" ) ,
1414+ CertificateStatus :: Reissued => String :: from_str ( & env, "Status: Reissued" ) ,
1415+ CertificateStatus :: NonCompliant => String :: from_str ( & env, "Status: Non-Compliant" ) ,
1416+ _ => String :: from_str ( & env, "Status: Inactive" ) ,
14121417 } ;
1413- violation_details = String :: from_str ( & env, "Certificate status is " ) ;
1414- violation_details. append ( & String :: from_str ( & env, status_msg) ) ;
1415- violation_details. append ( & String :: from_str ( & env, "; " ) ) ;
14161418 }
1417-
14181419 // 3. Provenance Check
1419- if cert. blockchain_anchor . is_none ( ) {
1420+ else if cert. blockchain_anchor . is_none ( ) {
14201421 is_compliant = false ;
1421- violation_details = String :: from_str ( & env, "Blockchain anchor is missing; " ) ;
1422+ violation_details = String :: from_str ( & env, "Missing Anchor " ) ;
14221423 }
14231424
14241425 if !is_compliant {
@@ -1440,7 +1441,7 @@ impl CertificateContract {
14401441 & env,
14411442 & certificate_id,
14421443 "Standard Automated Check" ,
1443- & violation_details. to_string ( ) ,
1444+ violation_details,
14441445 ) ;
14451446 record_audit (
14461447 & env,
@@ -1472,8 +1473,8 @@ impl CertificateContract {
14721473 require_initialized ( & env) ?;
14731474 require_compliance_officer ( & env, & officer) ?;
14741475
1475- let mut cert =
1476- storage :: get_certificate ( & env , & certificate_id ) . ok_or ( CertificateError :: CertificateNotFound ) ?;
1476+ let mut cert = storage :: get_certificate ( & env , & certificate_id )
1477+ . ok_or ( CertificateError :: CertificateNotFound ) ?;
14771478 cert. status = CertificateStatus :: NonCompliant ;
14781479 storage:: set_certificate ( & env, & certificate_id, & cert) ;
14791480
@@ -1485,7 +1486,7 @@ impl CertificateContract {
14851486 & env,
14861487 & certificate_id,
14871488 "Manual Compliance Override" ,
1488- & notes,
1489+ notes. clone ( ) ,
14891490 ) ;
14901491
14911492 record_audit (
@@ -1512,6 +1513,7 @@ impl CertificateContract {
15121513 CertificateStatus :: Expired => String :: from_str ( & env, "Expired" ) ,
15131514 CertificateStatus :: Suspended => String :: from_str ( & env, "Suspended" ) ,
15141515 CertificateStatus :: Reissued => String :: from_str ( & env, "Reissued" ) ,
1516+ CertificateStatus :: NonCompliant => String :: from_str ( & env, "Non-Compliant" ) ,
15151517 } ,
15161518 ) ;
15171519 report. set (
0 commit comments