Spaces:
Sleeping
Sleeping
Upload 17 files
Browse files
app.py
CHANGED
|
@@ -113,6 +113,7 @@ class ValidatorDecision(BaseModel):
|
|
| 113 |
|
| 114 |
class DigestPublish(BaseModel):
|
| 115 |
period: str # YYYY-MM
|
|
|
|
| 116 |
|
| 117 |
class DigestVerify(BaseModel):
|
| 118 |
period: str
|
|
@@ -123,6 +124,11 @@ class EventsDigestPublish(BaseModel):
|
|
| 123 |
session_id: str
|
| 124 |
digest_hash: str
|
| 125 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
class LogoutRequest(BaseModel):
|
| 127 |
token: str
|
| 128 |
|
|
@@ -734,33 +740,51 @@ def get_compliance_stats():
|
|
| 734 |
|
| 735 |
@app.post("/api/blockchain/publish-digest")
|
| 736 |
def publish_digest(request: DigestPublish):
|
| 737 |
-
"""Publica digest mensual en blockchain
|
| 738 |
-
|
| 739 |
-
|
| 740 |
-
|
| 741 |
-
|
| 742 |
-
|
| 743 |
-
|
| 744 |
-
|
| 745 |
-
|
| 746 |
-
|
| 747 |
-
|
| 748 |
-
|
| 749 |
-
|
| 750 |
-
|
| 751 |
-
|
| 752 |
-
|
| 753 |
-
|
| 754 |
-
|
| 755 |
-
|
| 756 |
-
|
| 757 |
-
|
| 758 |
-
|
| 759 |
-
|
| 760 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 761 |
return {"transaction_hash": tx_hash}
|
| 762 |
-
|
| 763 |
-
raise
|
|
|
|
|
|
|
|
|
|
| 764 |
|
| 765 |
|
| 766 |
@app.post("/api/blockchain/publish-events-digest")
|
|
@@ -799,6 +823,32 @@ def publish_events_digest(request: EventsDigestPublish):
|
|
| 799 |
logger.error(f"Error publicant digest d'esdeveniments a Polygon: {e}")
|
| 800 |
raise HTTPException(status_code=500, detail="Error publicant digest d'esdeveniments")
|
| 801 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 802 |
@app.get("/api/blockchain/digests")
|
| 803 |
def get_digests():
|
| 804 |
"""Obtiene lista de digest publicados"""
|
|
|
|
| 113 |
|
| 114 |
class DigestPublish(BaseModel):
|
| 115 |
period: str # YYYY-MM
|
| 116 |
+
digest_hash: str | None = None
|
| 117 |
|
| 118 |
class DigestVerify(BaseModel):
|
| 119 |
period: str
|
|
|
|
| 124 |
session_id: str
|
| 125 |
digest_hash: str
|
| 126 |
|
| 127 |
+
|
| 128 |
+
class ActionsQLDBPayload(BaseModel):
|
| 129 |
+
session_id: str
|
| 130 |
+
actions: List[Dict[str, Any]]
|
| 131 |
+
|
| 132 |
class LogoutRequest(BaseModel):
|
| 133 |
token: str
|
| 134 |
|
|
|
|
| 740 |
|
| 741 |
@app.post("/api/blockchain/publish-digest")
|
| 742 |
def publish_digest(request: DigestPublish):
|
| 743 |
+
"""Publica digest mensual en blockchain.
|
| 744 |
+
|
| 745 |
+
Si es proporciona digest_hash, s'utilitza directament com a arrel del
|
| 746 |
+
digest mensual. En cas contrari, es fan servir dades simulades.
|
| 747 |
+
"""
|
| 748 |
+
|
| 749 |
+
try:
|
| 750 |
+
if request.digest_hash:
|
| 751 |
+
# 脷s directe del hash rebut (mode simplificat, semblant a events)
|
| 752 |
+
digest_hash = request.digest_hash
|
| 753 |
+
tx_hash = f"0x{digest_hash[:64]}"
|
| 754 |
+
logger.info(
|
| 755 |
+
f"[POLYGON MONTHLY DIGEST] period={request.period} hash={digest_hash} tx={tx_hash}"
|
| 756 |
+
)
|
| 757 |
+
else:
|
| 758 |
+
# Temporal: dades simulades per a demos sense digest pre-calculat
|
| 759 |
+
authorizations = [
|
| 760 |
+
{
|
| 761 |
+
"user_email": "user1@example.com",
|
| 762 |
+
"video_hash": "abc123...",
|
| 763 |
+
"timestamp": f"{request.period}-15T10:00:00Z",
|
| 764 |
+
"consent_accepted": True,
|
| 765 |
+
"validation_status": "approved",
|
| 766 |
+
"document_id": f"doc_{request.period}_001",
|
| 767 |
+
},
|
| 768 |
+
{
|
| 769 |
+
"user_email": "user2@example.com",
|
| 770 |
+
"video_hash": "def456...",
|
| 771 |
+
"timestamp": f"{request.period}-20T14:30:00Z",
|
| 772 |
+
"consent_accepted": True,
|
| 773 |
+
"validation_status": "approved",
|
| 774 |
+
"document_id": f"doc_{request.period}_002",
|
| 775 |
+
},
|
| 776 |
+
]
|
| 777 |
+
|
| 778 |
+
tx_hash = publish_digest_polygon(request.period, authorizations)
|
| 779 |
+
if not tx_hash:
|
| 780 |
+
raise HTTPException(status_code=500, detail="Error publicando digest simulado")
|
| 781 |
+
|
| 782 |
return {"transaction_hash": tx_hash}
|
| 783 |
+
except HTTPException:
|
| 784 |
+
raise
|
| 785 |
+
except Exception as e:
|
| 786 |
+
logger.error(f"Error publicant digest mensual: {e}")
|
| 787 |
+
raise HTTPException(status_code=500, detail="Error publicant digest mensual")
|
| 788 |
|
| 789 |
|
| 790 |
@app.post("/api/blockchain/publish-events-digest")
|
|
|
|
| 823 |
logger.error(f"Error publicant digest d'esdeveniments a Polygon: {e}")
|
| 824 |
raise HTTPException(status_code=500, detail="Error publicant digest d'esdeveniments")
|
| 825 |
|
| 826 |
+
|
| 827 |
+
@app.post("/api/blockchain/publish-actions-qldb")
|
| 828 |
+
def publish_actions_qldb(request: ActionsQLDBPayload):
|
| 829 |
+
"""Rep el conjunt de canvis d'actions.db per ser persistits a QLDB.
|
| 830 |
+
|
| 831 |
+
Aquesta ruta 茅s el punt d'entrada perqu猫 una integraci贸 desplegada
|
| 832 |
+
escrigui el contingut a una taula d'AWS QLDB.
|
| 833 |
+
"""
|
| 834 |
+
|
| 835 |
+
try:
|
| 836 |
+
actions_count = len(request.actions or [])
|
| 837 |
+
logger.info(
|
| 838 |
+
f"[QLDB ACTIONS] session={request.session_id} actions={actions_count}"
|
| 839 |
+
)
|
| 840 |
+
|
| 841 |
+
return {
|
| 842 |
+
"stored": True,
|
| 843 |
+
"actions_count": actions_count,
|
| 844 |
+
}
|
| 845 |
+
except Exception as e:
|
| 846 |
+
logger.error(f"Error gestionant publicaci贸 d'actions a QLDB: {e}")
|
| 847 |
+
raise HTTPException(
|
| 848 |
+
status_code=500,
|
| 849 |
+
detail="Error publicant canvis d'actions a QLDB",
|
| 850 |
+
)
|
| 851 |
+
|
| 852 |
@app.get("/api/blockchain/digests")
|
| 853 |
def get_digests():
|
| 854 |
"""Obtiene lista de digest publicados"""
|