Skip to content

DamianTarnowski/BlobChatStorage

Repository files navigation

Blob Chat Storage

Własny serwis blob storage dla aplikacji czatowych w .NET 9.

🎯 Pełna Wizja Projektu

Sprawdź kompletny plan w ROADMAP.md

Budujemy zaawansowany blob storage z funkcjami dedykowanymi dla czatów:

  • Chunked upload z wznowieniem - GOTOWE!
  • Automatyczne miniaturki (WebP, 3 rozmiary) - GOTOWE!
  • SQLite z EF Core + hierarchiczna struktura - GOTOWE!
  • SignalR Real-time (perfect dla Blazor WASM!) - GOTOWE!
  • 🚧 Inteligentna kompresja (WebP, transkodowanie wideo)
  • 🚧 Szyfrowanie AES-256 + autoryzacja tokenowa
  • 🚧 Buforowanie wielopoziomowe (Memory + Redis + CDN)
  • 🚧 Świadomość kontekstu rozmów
  • 🚧 Deduplikacja + wyszukiwanie pełnotekstowe
  • 🚧 Monitorowanie i analiza użycia

To już production-ready blob storage klasy enterprise z inteligentną kompresją i pełnym test coverage! 🚀

Co zostało zrealizowane

Podstawowa struktura projektu

  • Projekt API (BlobChatStorage.Api)
  • Projekt Core z modelami i serwisami (BlobChatStorage.Core)
  • Struktura dla Storage (BlobChatStorage.Storage)

Model danych

  • BlobInfo - model opisujący przechowywany plik
  • Zawiera: Id, FileName, ContentType, Size, CreatedAt, FilePath, ChatId

Serwis przechowywania

  • IBlobService - interfejs dla operacji na blobach
  • SqliteBlobService - implementacja z SQLite (zastąpiła JSON)
  • Hierarchiczna struktura katalogów: /storage/{rok}/{miesiąc}/{dzień}/{blobId}
  • Entity Framework Core z SQLite dla metadanych

Baza danych SQLite

  • Tabele: Blobs, UploadSessions, Chunks, Thumbnails
  • Wydajne indeksy na ChatId, CreatedAt, Status, BlobId
  • Relacje FK między sesjami/kawałkami i blobami/miniaturkami
  • Automatyczna migracja przy starcie
  • SixLabors.ImageSharp do przetwarzania obrazów

REST API

  • POST /upload - przesyłanie pliku (z parametrem chatId)
  • GET /download/{blobId} - pobieranie pliku (właściwy Content-Type, Range streaming)
  • GET /files/{chatId} - lista plików w czacie
  • GET /files - wszystkie pliki

Chunked Upload (Przesyłanie w kawałkach)

  • POST /chunked/initiate - rozpoczęcie sesji chunked upload
  • POST /chunked/{uploadId}/chunk/{chunkNumber} - przesłanie kawałka
  • POST /chunked/{uploadId}/finalize - finalizacja (składanie kawałków)
  • GET /chunked/{uploadId}/status - sprawdzenie postępu
  • DELETE /chunked/{uploadId} - anulowanie sesji

Pipeline Miniaturek (Automatyczne generowanie)

  • GET /thumbnails/{blobId}/{size} - pobierz miniaturkę (Small/Medium/Large)
  • GET /thumbnails/{blobId} - lista wszystkich miniaturek dla bloba
  • POST /thumbnails/{blobId}/generate - wygeneruj miniaturki dla istniejącego pliku
  • DELETE /thumbnails/{blobId} - usuń wszystkie miniaturki
  • Automatyczne: miniaturki generowane przy uploadzieji obrazów!

SignalR Real-time (Perfect dla Blazor WASM!)

  • /uploadHub - SignalR hub dla wszystkich notyfikacji
  • Progress uploadu: realtime postęp każdego kawałka
  • Finalizacja: powiadomienie o składaniu plików
  • Miniaturki: instant notification gdy są gotowe
  • Chat notifications: nowe pliki dla wszystkich w czacie
  • Błędy/anulowanie: realtime feedback

Inteligentny Silnik Kompresji (Production Ready!)

  • WebP Conversion: JPEG/PNG → WebP z adjustable quality (85% default)
  • Text Compression: GZip dla JSON, XML, CSV, logs z significant space savings
  • Smart Detection: Automatyczne rozpoznawanie i recommendation engine
  • Automatic Pipeline: Integracja z chunked upload - kompresja po finalizacji
  • 7 API endpoints: info, manual compression, download, analytics, management
  • Performance Metrics: compression ratios, processing time, success statistics

Kompletna Struktura Testów (59 testów)

  • Unit testy: SqliteBlobService, ChunkedUploadService, ThumbnailService, CompressionService
  • Integration testy: API endpoints z WebApplicationFactory
  • Test infrastructure: xUnit, Moq, InMemory EF, AspNetCore.Mvc.Testing
  • CI/CD ready: dotnet test z pełnym coverage

Uruchomienie

cd src/BlobChatStorage.Api
dotnet run

API będzie dostępne na: http://localhost:5139

Konfiguracja (CORS, szyfrowanie, ephemeral, AV, limity, signed URLs)

  • Cors.AllowedOrigins – dodaj domeny Twojego frontendu (WASM/SPA) i debugowe localhosty
  • Storage.AtRestEncryptionEnabled – włącza szyfrowanie plików w spoczynku (AES‑GCM 256)
  • Storage.AtRestEncryptionKeyBase64 – klucz 32 bajty w Base64 (wymagany przy włączeniu)
  • Ephemeral – domyślny TTL, okres łaski soft-delete, harmonogram cleanup
  • ContentScan – AV skanowanie (Noop/ClamAV), komenda/args, czas oczekiwania
  • UploadLimits – maksymalny rozmiar pliku i dopuszczalne typy MIME
  • SignedUrls – sekret HMAC, TTL i tolerancja zegara do linków tymczasowych

Przykład (src/BlobChatStorage.Api/appsettings.json):

{
  "Cors": { "AllowedOrigins": ["https://localhost:7138", "https://localhost:7038"] },
  "Storage": { "AtRestEncryptionEnabled": false, "AtRestEncryptionKeyBase64": "" },
  "Ephemeral": {
    "EnableDefaultExpiry": false,
    "DefaultTtl": "00:00:00",
    "SoftDeleteGracePeriod": "7.00:00:00",
    "CleanupInterval": "00:15:00",
    "EnableAutoCleanup": false,
    "PhysicalDeleteOnCleanup": false
  },
  "ContentScan": {
    "Enabled": false,
    "Provider": "Noop",
    "Command": "clamscan",
    "Args": "--no-summary --stdout \"{file}\"",
    "TimeoutSeconds": 30
  },
  "UploadLimits": {
    "MaxFileSizeBytes": 524288000,
    "AllowedContentTypes": [
      "image/jpeg", "image/png", "image/webp", "video/mp4",
      "text/plain", "application/pdf", "application/zip"
    ]
  },
  "SignedUrls": {
    "SecretKeyBase64": "", // 32 bajty Base64 (HMACSHA256)
    "DefaultTtlSeconds": 300,
    "AllowedDriftSeconds": 30
  }
}

Rate Limiting

  • uploads: 30/min, chunks: 120/min, downloads: 300/min, admin: 60/min (per użytkownik/IP)

Signed URLs – skrót

  • Generuj: POST /files/{blobId}/signed-url → zwraca URL /signed/{token} ważny krótko (domyślnie 5 min)
  • Pobierz: GET /signed/{token} – bez JWT, z obsługą Range (lepszy UX dla dużych plików)
  • Zabezpieczenie: HMAC (HMACSHA256) z sekretem w SignedUrls.SecretKeyBase64 (w Development dopuszczony tryb bez weryfikacji, w produkcji obowiązkowo włącz)

Presigned Upload – skrót

  • Inicjuj: POST /uploads/presign (JWT w prod; w Dev dopuszczony anonimowo)
  • Wyślij: PUT /uploads/presigned/{token} lub PUT /uploads/presigned?token={token} (bez JWT)
  • Wymagania: poprawny Content-Length (jeśli size>0 w tokenie); opcjonalne jednorazowe użycie tokena (once=1)
  • Tokeny są odporne na kropki w payloadzie (podpis to część po ostatniej kropce)
  • Szczegóły: zobacz docs/SIGNED_UPLOADS.md

Testowanie

Upload pliku

curl -X POST -F "file=@test.txt" -F "chatId=chat123" http://localhost:5139/upload

Lista plików w czacie

curl http://localhost:5139/files/chat123

Download pliku

curl http://localhost:5139/download/{blobId} -o downloaded_file.txt

Chunked Upload

1. Rozpocznij sesję

curl -X POST "http://localhost:5139/chunked/initiate?fileName=bigfile.zip&totalSize=100000000&chatId=chat123"

2. Przesyłaj kawałki (przykład dla kawałka 0)

curl -X POST -F "chunk=@chunk_0.bin" "http://localhost:5139/chunked/{uploadId}/chunk/0"

3. Sprawdź status

curl "http://localhost:5139/chunked/{uploadId}/status"

4. Finalizuj upload

curl -X POST "http://localhost:5139/chunked/{uploadId}/finalize"

Miniaturki

1. Upload obrazu (automatyczne generowanie miniaturek)

curl -X POST -F "file=@photo.jpg" -F "chatId=chat123" http://localhost:5139/upload

2. Pobierz miniaturkę w małym rozmiarze

curl "http://localhost:5139/thumbnails/{blobId}/Small" -o thumbnail_small.webp

3. Lista dostępnych miniaturek

curl "http://localhost:5139/thumbnails/{blobId}"

4. Wygeneruj miniaturki dla istniejącego pliku

curl -X POST "http://localhost:5139/thumbnails/{blobId}/generate"

SignalR dla Blazor WASM

Pełny przykład integracji z Blazor WASM w docs/BLAZOR_SIGNALR_EXAMPLE.md

Szybki start:

// 1. Połączenie
var connection = new HubConnectionBuilder()
    .WithUrl("https://localhost:7038/uploadHub")
    .Build();

// 2. Dołącz do grup
await connection.InvokeAsync("JoinUploadGroup", uploadId);
await connection.InvokeAsync("JoinChatGroup", chatId);

// 3. Nasłuchuj eventów real-time
connection.On<string, int, int, double>("OnChunkUploaded", 
    (uploadId, chunkNumber, totalChunks, progressPercent) =>
    {
        // Aktualizuj progress bar w real-time!
    });

connection.On<string, object>("OnNewFileInChat", 
    (chatId, fileInfo) =>
    {
        // Nowy plik w czacie - pokaż natychmiast!
    });

Uruchamianie testów

# Wszystkie testy
dotnet test

# Tylko unit testy Core
dotnet test tests/BlobChatStorage.Core.Tests/

# Tylko integration testy API
dotnet test tests/BlobChatStorage.Api.Tests/

# Z verbose output
dotnet test --verbosity normal

Compression API

# Pobierz informacje o kompresji
curl http://localhost:5000/compression/{blobId}

# Pobierz wszystkie kompresje dla bloba
curl http://localhost:5000/compression/{blobId}/all

# Kompresuj istniejący blob (manual trigger)
curl -X POST http://localhost:5000/compression/{blobId}/compress \
  -H "Content-Type: application/json" \
  -d '{"Quality": 90, "PreferredType": "WebP"}'

# Pobierz skompresowany plik
curl http://localhost:5000/compression/{blobId}/download -o compressed_file

# Usuń skompresowane pliki
curl -X DELETE http://localhost:5000/compression/{blobId}

# Statystyki kompresji
curl http://localhost:5000/compression/stats

Test Coverage

70 testów obejmuje:

  • Unit testy (48 testów): SqliteBlobService, ChunkedUploadService, ThumbnailService, CompressionService
  • Integration testy (5 testów): API endpoints, health checks, authentication
  • Compression tests (11 testów): WebP conversion, GZip compression, file detection, stats
  • Mock testing: Dependency injection, Service isolation
  • Database testing: In-memory SQLite, Entity Framework scenarios
  • File system testing: Temporary storage, cleanup scenarios

📚 Dokumentacja

Deployment & Production

Integration

Architecture

Następne kroki

🔄 Zaplanowane funkcje:

  • Przesyłanie w kawałkach (chunked upload) - ZREALIZOWANE!
  • SQLite dla metadanych - ZREALIZOWANE!
  • Pipeline miniaturek - ZREALIZOWANE!
  • SignalR Real-time - ZREALIZOWANE!
  • Kompletna struktura testów - ZREALIZOWANE!
  • Inteligentny silnik kompresji (WebP + Text) - ZREALIZOWANE!
  • Wznowienie przerwanych uploadów
  • Video transcoding - następny krok
  • Szyfrowanie AES-256
  • Buforowanie wielopoziomowe (Redis + CDN)
  • Deduplikacja plików
  • Skanowanie wirusów

Struktura plików

storage/
├── 2025/                    # Finalne pliki w hierarchii
│   └── 01/
│       └── 06/
│           └── {blobId}
├── uploads/                 # Chunked upload
│   ├── sessions/           # Metadane sesji (.json)
│   ├── {uploadId}/         # Kawałki tymczasowe
│   └── temp_{uploadId}     # Pliki tymczasowe
├── thumbnails/             # Miniaturki
│   └── {blobId}/
│       ├── small.webp      # 150px
│       ├── medium.webp     # 400px
│       └── large.webp      # 800px
├── blobs.db                # SQLite baza danych
└── metadata.json           # Stare metadane (deprecated)

Kluczowe funkcje:

  • Hierarchiczna struktura plików według daty
  • Chunked upload z tymczasowymi plikami i składaniem
  • Automatyczne miniaturki w trzech rozmiarach (WebP)
  • SQLite database dla wszystkich metadanych
  • Integralna integralność - miniaturki usuwane z plikami

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors