TRON -> TRON_MAINNET
This commit is contained in:
@@ -217,8 +217,14 @@ func (s *Service) BatchResolveDocuments(ctx context.Context, req *documentsv1.Ba
|
||||
for _, ref := range refs {
|
||||
meta := &documentsv1.DocumentMeta{PaymentRef: ref}
|
||||
if record := recordByRef[ref]; record != nil {
|
||||
meta.AvailableTypes = toProtoTypes(record.Available)
|
||||
meta.ReadyTypes = toProtoTypes(record.Ready)
|
||||
record.Normalize()
|
||||
available := []model.DocumentType{model.DocumentTypeAct}
|
||||
ready := make([]model.DocumentType, 0, 1)
|
||||
if path, ok := record.StoragePaths[model.DocumentTypeAct]; ok && path != "" {
|
||||
ready = append(ready, model.DocumentTypeAct)
|
||||
}
|
||||
meta.AvailableTypes = toProtoTypes(available)
|
||||
meta.ReadyTypes = toProtoTypes(ready)
|
||||
}
|
||||
items = append(items, meta)
|
||||
}
|
||||
@@ -294,8 +300,9 @@ func (s *Service) GetDocument(ctx context.Context, req *documentsv1.GetDocumentR
|
||||
record.Normalize()
|
||||
|
||||
targetType := model.DocumentTypeFromProto(docType)
|
||||
if !containsDocType(record.Available, targetType) {
|
||||
return nil, status.Error(codes.NotFound, "document type not available")
|
||||
|
||||
if docType != documentsv1.DocumentType_DOCUMENT_TYPE_ACT {
|
||||
return nil, status.Error(codes.Unimplemented, "document type not implemented")
|
||||
}
|
||||
|
||||
if path, ok := record.StoragePaths[targetType]; ok && path != "" {
|
||||
@@ -310,10 +317,6 @@ func (s *Service) GetDocument(ctx context.Context, req *documentsv1.GetDocumentR
|
||||
}, nil
|
||||
}
|
||||
|
||||
if docType != documentsv1.DocumentType_DOCUMENT_TYPE_ACT {
|
||||
return nil, status.Error(codes.Unimplemented, "document type not implemented")
|
||||
}
|
||||
|
||||
content, hash, genErr := s.generateActPDF(record.Snapshot)
|
||||
if genErr != nil {
|
||||
logger.Warn("Failed to generate document", zap.Error(genErr))
|
||||
@@ -328,7 +331,6 @@ func (s *Service) GetDocument(ctx context.Context, req *documentsv1.GetDocumentR
|
||||
|
||||
record.StoragePaths[targetType] = path
|
||||
record.Hashes[targetType] = hash
|
||||
record.Ready = appendUnique(record.Ready, targetType)
|
||||
if updateErr := s.storage.Documents().Update(ctx, record); updateErr != nil {
|
||||
logger.Warn("Failed to update document record", zap.Error(updateErr))
|
||||
return nil, status.Error(codes.Internal, updateErr.Error())
|
||||
@@ -375,24 +377,7 @@ func (s *Service) generateActPDF(snapshot model.ActSnapshot) ([]byte, string, er
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
fileHash := sha256.Sum256(finalBytes)
|
||||
return finalBytes, hex.EncodeToString(fileHash[:]), nil
|
||||
}
|
||||
|
||||
func containsDocType(list []model.DocumentType, target model.DocumentType) bool {
|
||||
for _, entry := range list {
|
||||
if entry == target {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func appendUnique(list []model.DocumentType, value model.DocumentType) []model.DocumentType {
|
||||
if containsDocType(list, value) {
|
||||
return list
|
||||
}
|
||||
return append(list, value)
|
||||
return finalBytes, footerHex, nil
|
||||
}
|
||||
|
||||
func toProtoTypes(types []model.DocumentType) []documentsv1.DocumentType {
|
||||
|
||||
@@ -3,8 +3,6 @@ package documents
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -100,14 +98,11 @@ func TestGetDocument_IdempotentAndHashed(t *testing.T) {
|
||||
ExecutorFullName: "Jane Doe",
|
||||
Amount: decimal.RequireFromString("100.00"),
|
||||
Currency: "USD",
|
||||
OrgLegalName: "Acme Corp",
|
||||
OrgAddress: "42 Galaxy Way",
|
||||
}
|
||||
|
||||
record := &model.DocumentRecord{
|
||||
PaymentRef: "PAY-123",
|
||||
Snapshot: snapshot,
|
||||
Available: []model.DocumentType{model.DocumentTypeAct},
|
||||
}
|
||||
|
||||
documentsStore := &stubDocumentsStore{record: record}
|
||||
@@ -144,12 +139,15 @@ func TestGetDocument_IdempotentAndHashed(t *testing.T) {
|
||||
t.Fatalf("expected content on first call")
|
||||
}
|
||||
|
||||
hash1 := sha256.Sum256(resp1.Content)
|
||||
stored := record.Hashes[model.DocumentTypeAct]
|
||||
if stored == "" {
|
||||
t.Fatalf("expected stored hash")
|
||||
}
|
||||
if stored != hex.EncodeToString(hash1[:]) {
|
||||
footerHash := extractFooterHash(resp1.Content)
|
||||
if footerHash == "" {
|
||||
t.Fatalf("expected footer hash in PDF")
|
||||
}
|
||||
if stored != footerHash {
|
||||
t.Fatalf("stored hash mismatch: got %s", stored)
|
||||
}
|
||||
|
||||
@@ -174,3 +172,24 @@ func TestGetDocument_IdempotentAndHashed(t *testing.T) {
|
||||
t.Fatalf("expected document load on second call")
|
||||
}
|
||||
}
|
||||
|
||||
func extractFooterHash(pdf []byte) string {
|
||||
prefix := []byte("Document integrity hash: ")
|
||||
idx := bytes.Index(pdf, prefix)
|
||||
if idx == -1 {
|
||||
return ""
|
||||
}
|
||||
start := idx + len(prefix)
|
||||
end := start
|
||||
for end < len(pdf) && isHexDigit(pdf[end]) {
|
||||
end++
|
||||
}
|
||||
if end-start != 64 {
|
||||
return ""
|
||||
}
|
||||
return string(pdf[start:end])
|
||||
}
|
||||
|
||||
func isHexDigit(b byte) bool {
|
||||
return (b >= '0' && b <= '9') || (b >= 'a' && b <= 'f') || (b >= 'A' && b <= 'F')
|
||||
}
|
||||
|
||||
@@ -23,8 +23,6 @@ func TestTemplateRenderer_Render(t *testing.T) {
|
||||
ExecutorFullName: "Jane Doe",
|
||||
Amount: decimal.RequireFromString("123.45"),
|
||||
Currency: "USD",
|
||||
OrgLegalName: "Acme Corp",
|
||||
OrgAddress: "42 Galaxy Way",
|
||||
}
|
||||
|
||||
blocks, err := tmpl.Render(snapshot)
|
||||
@@ -54,15 +52,15 @@ func TestTemplateRenderer_Render(t *testing.T) {
|
||||
if kv == nil {
|
||||
t.Fatalf("expected kv block")
|
||||
}
|
||||
foundOrg := false
|
||||
foundExecutor := false
|
||||
for _, row := range kv.Rows {
|
||||
if len(row) >= 2 && row[0] == "Customer" && row[1] == snapshot.OrgLegalName {
|
||||
foundOrg = true
|
||||
if len(row) >= 2 && row[0] == "Executor" && row[1] == snapshot.ExecutorFullName {
|
||||
foundExecutor = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !foundOrg {
|
||||
t.Fatalf("expected org name in kv block")
|
||||
if !foundExecutor {
|
||||
t.Fatalf("expected executor name in kv block")
|
||||
}
|
||||
|
||||
table := findBlock(blocks, renderer.TagTable)
|
||||
|
||||
Reference in New Issue
Block a user