# LOCKER ![Estado](https://img.shields.io/badge/Estado-PLANIFICADO-yellow) **Gateway de Almacenamiento - Ecosistema TZZR** ## Cloudflare R2 (Actualizado 2025-12-22) ### Estado de Buckets | Bucket | Estado | Objetos | Contenido | |--------|--------|---------|-----------| | architect | OK | 0 | vacío | | hst | OK | 0 | vacío | | deck | OK | 1 | test.txt (5 bytes) | | corp | OK | 0 | vacío | | locker | OK | 0 | vacío | **Resultado:** 5/5 buckets accesibles ### Credenciales R2 ``` Endpoint: https://7dedae6030f5554d99d37e98a5232996.r2.cloudflarestorage.com Access Key: ecddc771824c3cb3417d9451780db3d2 Secret Key: c8138e2597100ffb7dd1477ad722c0214f86097cd968752aea3cfcea5d54dbac ``` Token: `locker-full-access` (Object Read & Write, todos los buckets) ## Descripción LOCKER es el **gateway de almacenamiento** del ecosistema. Abstrae el almacenamiento físico permitiendo guardar y recuperar archivos usando referencias `locker://`. Actualmente usa almacenamiento local/Nextcloud, con plan de migrar a solución descentralizada. ## Arquitectura ``` ┌─────────────────────────────────────────────────────────────────┐ │ LOCKER │ │ (Gateway de Almacenamiento) │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ API GATEWAY │ │ │ │ locker://corp/facturas/001.pdf → /files/corp/... │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ STORAGE ROUTER │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ │ ┌─────────────────┼─────────────────┐ │ │ ▼ ▼ ▼ │ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │ │ Local │ │ Nextcloud │ │ IPFS │ │ │ │ (actual) │ │ (sync) │ │ (futuro) │ │ │ └───────────┘ └───────────┘ └───────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` ## Referencias LOCKER Formato: `locker://{namespace}/{path}` | Namespace | Descripción | Ejemplo | |-----------|-------------|---------| | corp | Documentos empresariales | `locker://corp/facturas/FAC-2025-001.pdf` | | deck | Archivos personales | `locker://deck/fitness/progress/week1.jpg` | | hst | Imágenes de tags | `locker://hst/icons/fit.png` | | factory | Artefactos generados | `locker://factory/artifacts/abc123.md` | | emails | Adjuntos de correo | `locker://emails/adjuntos/2025/01/doc.pdf` | ## API ### PUT /api/files/{path} Subir archivo. ```bash curl -X PUT https://locker.tzzr.me/api/files/corp/facturas/001.pdf \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/pdf" \ --data-binary @factura.pdf ``` **Response:** ```json { "ref": "locker://corp/facturas/001.pdf", "url": "https://locker.tzzr.me/corp/facturas/001.pdf", "sha256": "abc123...", "size_bytes": 125000 } ``` ### GET /api/files/{path} Descargar archivo. ```bash curl https://locker.tzzr.me/api/files/corp/facturas/001.pdf \ -H "Authorization: Bearer $API_KEY" \ -o factura.pdf ``` ### POST /api/signed-url Generar URL firmada (acceso temporal). ```json { "path": "corp/facturas/001.pdf", "expires_in": 3600 } ``` **Response:** ```json { "signed_url": "https://locker.tzzr.me/corp/facturas/001.pdf?token=xyz&expires=..." } ``` ### DELETE /api/files/{path} Eliminar archivo. ## Integración ### Con THE FACTORY ```javascript // FACTORY sube artefactos generados a LOCKER const factory = new FactoryClient(); const result = await factory.getJobResultToLocker(jobId, 'corp/facturas/001.pdf'); // Returns: { locker_ref: "locker://corp/facturas/001.pdf" } ``` ### Con CLARA (CORP) ```javascript // CLARA guarda facturas certificadas const clara = new Clara(); const stored = await clara.storeInLocker(invoiceContent, 'factura', { numero: 'FAC-2025-001' }); // locker://corp/facturas/FAC-2025-001.pdf ``` ### Con DECK ```javascript // DECK guarda fotos de progreso const response = await fetch('https://locker.tzzr.me/api/files/deck/fitness/progress/week1.jpg', { method: 'PUT', body: imageBlob }); ``` ### Con Emails ```javascript // Adjuntos de email van a LOCKER const attachment = await locker.upload( `emails/adjuntos/2025/01/${emailId}_${filename}`, content ); // locker://emails/adjuntos/2025/01/msg001_documento.pdf ``` ## Deduplicación LOCKER usa SHA-256 para deduplicar: ```javascript // Si el hash ya existe, retorna referencia existente const result = await locker.upload(path, content); if (result.deduplicated) { console.log('Archivo ya existía:', result.existing_ref); } ``` ## Sync con Nextcloud LOCKER sincroniza con Nextcloud para acceso desde múltiples dispositivos: ``` LOCKER (API) ←→ Local Storage ←→ Nextcloud Sync │ ▼ Desktop/Mobile Apps ``` ## Estructura de Almacenamiento ``` /data/locker/ ├── corp/ │ ├── facturas/ │ │ └── FAC-2025-0001.pdf │ ├── pedidos/ │ └── productos/ ├── deck/ │ ├── fitness/ │ │ ├── progress/ │ │ └── plans/ │ └── documents/ ├── hst/ │ └── icons/ ├── factory/ │ └── artifacts/ └── emails/ └── adjuntos/ ``` ## Roadmap: Descentralización Plan de migración a almacenamiento descentralizado: ``` Fase 1 (actual): Local + Nextcloud Fase 2: IPFS para archivos públicos (HST icons) Fase 3: Arweave para documentos certificados Fase 4: Filecoin para backup completo ``` ## Estructura del Proyecto ``` locker/ ├── src/ │ ├── api.py # API Gateway │ ├── storage/ │ │ ├── local.py │ │ ├── nextcloud.py │ │ └── ipfs.py (futuro) │ └── dedup.py # Deduplicación ├── docker/ │ └── docker-compose.yml └── README.md ``` ## Repositorios Relacionados | Repo | Rol | |------|-----| | [the-factory](https://github.com/tzzrgit/the-factory) | Guarda artefactos | | [corp](https://github.com/tzzrgit/corp) | Guarda facturas | | [deck](https://github.com/tzzrgit/deck) | Guarda archivos personales | | [hst-image-server](https://github.com/tzzrgit/hst-image-server) | Imágenes HST | ## Roadmap - [x] API básica (PUT/GET/DELETE) - [x] URLs firmadas - [x] Deduplicación SHA-256 - [x] Sync Nextcloud - [ ] IPFS para HST - [ ] Arweave para certificados - [ ] Compresión automática - [ ] CDN para assets públicos