Cluster ERP'deki her kayıt, çekirdekteki iki ortak tablo üzerinden dosya ve not taşıyabilir. Bu sayfa core/attachments.py, core/notes.py, server/routes/attachments.py ve server/routes/notes.py içindeki tabloları, servisleri ve rotaları, core/upload_policy.py içindeki yükleme politikasını ve core/storage.py içindeki depolama arka uçlarını listeler. documents modülünün sürümlü belge yönetimi ayrı bir özelliktir; bkz. documents.
Kapsam ve kaynak¶
- Tanımlandığı yer:
src/cluster_erp/core/attachments.py(Attachment,AttachmentService),src/cluster_erp/core/notes.py(Note,NoteService),src/cluster_erp/core/upload_policy.py(check_upload),src/cluster_erp/core/storage.py(StorageBackend,create_storage_backend),src/cluster_erp/server/routes/attachments.py,src/cluster_erp/server/routes/notes.py - Sayı: 8 ek rotası ve 6 not rotası (
@router.dekoratörlerinden sayıldı); 3 depolama arka ucu sınıfı; 40 varsayılan izinli uzantı
İki tablo da üst kayda yabancı anahtar olmadan entity_type ve entity_id ile bağlanır; böylece her varlık onları kullanabilir.
Ekler¶
core_attachments, BaseModel'den türer ve şu sütunları ekler (src/cluster_erp/core/attachments.py:51-63):
| Sütun | Tür | Anlamı | Kaynak |
|---|---|---|---|
code |
String(20), benzersiz |
attachment sırasından iş kodu |
src/cluster_erp/core/attachments.py:54, src/cluster_erp/core/attachments.py:123 |
entity_type |
String(50) |
Üst kaydın türü | src/cluster_erp/core/attachments.py:55 |
entity_id |
UUID |
Üst kaydın kimliği | src/cluster_erp/core/attachments.py:56 |
filename |
String(255) |
Saklanan ad: rastgele onaltılık ad ve temizlenmiş uzantı | src/cluster_erp/core/attachments.py:57, src/cluster_erp/core/attachments.py:124-125 |
original_filename |
String(255) |
Kullanıcının yüklediği ad | src/cluster_erp/core/attachments.py:58 |
content_type |
String(100) |
Yüklemenin bildirdiği içerik türü | src/cluster_erp/core/attachments.py:59 |
file_size |
BigInteger |
Bayt cinsinden boyut | src/cluster_erp/core/attachments.py:60 |
storage_path |
String(500) |
Depolama arka ucundaki anahtar | src/cluster_erp/core/attachments.py:61 |
sha256 |
String(64) |
İçeriğin SHA-256 özeti | src/cluster_erp/core/attachments.py:62 |
description |
Text |
İsteğe bağlı açıklama | src/cluster_erp/core/attachments.py:63 |
Depolama anahtarı attachments/<entity_type>/<entity_id>/<stored name> biçimindedir; çok kiracılı bir düğümde başına tenants/<tenant key>/ eklenir (src/cluster_erp/core/attachments.py:38-48). İndirmeler safe_content_disposition ile kurulan bir Content-Disposition başlığı taşır; bu işlev ASCII addan tırnak, ters bölü, satır sonu ve noktalı virgül karakterlerini çıkarır ve UTF-8 adı yüzde kodlar (src/cluster_erp/core/attachments.py:24-35).
AttachmentService yöntemleri (src/cluster_erp/core/attachments.py:88-206):
| Yöntem | Davranış | Kaynak |
|---|---|---|
list_for_entity |
Bir kaydın canlı ekleri | src/cluster_erp/core/attachments.py:93-104 |
get |
Tek bir canlı ek | src/cluster_erp/core/attachments.py:106-112 |
create |
Baytları depoya kaydeder, sonra satırı ekler | src/cluster_erp/core/attachments.py:114-143 |
update |
description veya original_filename değiştirir |
src/cluster_erp/core/attachments.py:145-153 |
delete |
deleted_at ayarlar; saklanan dosya kalır |
src/cluster_erp/core/attachments.py:155-161 |
bulk_delete |
bulk_soft_delete ile birçoğunu kullanımdan kaldırır |
src/cluster_erp/core/attachments.py:163-166 |
get_file_data |
Baytları depodan yükler | src/cluster_erp/core/attachments.py:168-169 |
replace_file |
Eski saklanan dosyayı siler, yenisini kaydeder ve satırı günceller | src/cluster_erp/core/attachments.py:171-197 |
count_for_entity |
Bir kaydın canlı ek sayısı | src/cluster_erp/core/attachments.py:199-206 |
Ek rotaları¶
Yönlendirici öneki /api/v1/attachments'tır (src/cluster_erp/server/routes/attachments.py:27).
| Yöntem ve yol | İzin | Amaç | Kaynak |
|---|---|---|---|
POST / (multipart: entity_type, entity_id, description, file) |
attachment.create |
Dosya yükle | src/cluster_erp/server/routes/attachments.py:62-85 |
GET /count/{entity_type}/{entity_id} |
attachment.read |
Bir kaydın dosyalarını say | src/cluster_erp/server/routes/attachments.py:88-99 |
GET /{attachment_id}/download |
attachment.download |
Baytları indir | src/cluster_erp/server/routes/attachments.py:102-121 |
GET /{entity_type}/{entity_id} |
attachment.read |
Bir kaydın dosyalarını listele | src/cluster_erp/server/routes/attachments.py:124-135 |
PUT /{attachment_id}/replace |
attachment.update |
Dosyayı değiştir | src/cluster_erp/server/routes/attachments.py:138-162 |
PUT /{attachment_id} |
attachment.update |
Açıklamayı veya adı değiştir | src/cluster_erp/server/routes/attachments.py:165-181 |
POST /bulk-delete |
attachment.bulk_delete |
Birçoğunu kullanımdan kaldır | src/cluster_erp/server/routes/attachments.py:184-199 |
DELETE /{attachment_id} |
attachment.delete |
Birini kullanımdan kaldır | src/cluster_erp/server/routes/attachments.py:202-215 |
Dosyası eksik bir satırın indirilmesi HTTP 404 ile FILE_NOT_FOUND_ON_DISK yanıtı verir (src/cluster_erp/server/routes/attachments.py:114-115).
Yükleme politikası¶
check_upload(filename, data, allowed) kabul edilen uzantıyı döndürür ya da UPLOAD_TYPE_REFUSED kodu ve HTTP 415 ile AppError yükseltir (src/cluster_erp/core/upload_policy.py:65-84). İki denetim uygular:
- Küçük harfli uzantı izin listesinde olmalıdır:
attachment_allowed_extensionsayarı ya daDEFAULT_ALLOWED_EXTENSIONSiçindeki 40 varsayılan (src/cluster_erp/core/upload_policy.py:21-27,src/cluster_erp/config/settings.py:368-374). - Bilinen dosya imzası olan 24 uzantı için içerik o imzayla başlamalıdır (
src/cluster_erp/core/upload_policy.py:30-55,src/cluster_erp/core/upload_policy.py:76-82).
Yükleme rotası check_upload işlevini yapılandırılmış listeyle çağırır (src/cluster_erp/server/routes/attachments.py:73-75). Modül belge dizgisi yürütülebilir dosyaların ve betiklerin listede olmadığını belirtir (src/cluster_erp/core/upload_policy.py:1-10).
Notlar¶
core_notes, BaseModel'den türer ve code, entity_type, entity_id ve content ekler (src/cluster_erp/core/notes.py:17-23). NoteCreate, entity_type (en fazla 50 karakter), entity_id ve boş olmayan content alır; NoteUpdate content alır (src/cluster_erp/core/notes.py:26-33). NoteService notları listeler, getirir, oluşturur (note sırasından bir kodla), günceller, kullanımdan kaldırır, toplu kullanımdan kaldırır ve sayar (src/cluster_erp/core/notes.py:48-114).
Not rotaları¶
Yönlendirici öneki /api/v1/notes'tur (src/cluster_erp/server/routes/notes.py:14).
| Yöntem ve yol | İzin | Amaç | Kaynak |
|---|---|---|---|
GET /{entity_type}/{entity_id} |
note.read |
Bir kaydın notlarını listele | src/cluster_erp/server/routes/notes.py:33-43 |
GET /count/{entity_type}/{entity_id} |
note.read |
Bir kaydın notlarını say | src/cluster_erp/server/routes/notes.py:46-56 |
POST / |
note.create |
Not oluştur | src/cluster_erp/server/routes/notes.py:59-68 |
PUT /{note_id} |
note.update |
Notu değiştir | src/cluster_erp/server/routes/notes.py:71-86 |
POST /bulk-delete |
note.bulk_delete |
Birçoğunu kullanımdan kaldır | src/cluster_erp/server/routes/notes.py:89-101 |
DELETE /{note_id} |
note.delete |
Birini kullanımdan kaldır | src/cluster_erp/server/routes/notes.py:104-116 |
Depolama arka uçları¶
StorageBackend, save, load, delete ve exists yöntemlerini taşıyan bir protokoldür (src/cluster_erp/core/storage.py:11-18). Lifespan süreç başına bir arka uç oluşturur ve app.state.storage üzerinde saklar (src/cluster_erp/server/app.py:65-75, src/cluster_erp/server/app.py:92).
| Sınıf | Nerede saklar | Notlar | Kaynak |
|---|---|---|---|
LocalStorageBackend |
Diskte bir klasör (storage_path) |
.. içeren veya kökün dışına çözülen anahtarları reddeder |
src/cluster_erp/core/storage.py:21-48 |
S3StorageBackend |
Bir S3 veya S3 uyumlu kova | İsteğe bağlı anahtar öneki; engelleyen istemci çağrıları bir iş parçacığında çalışır | src/cluster_erp/core/storage.py:51-135 |
EncryptedStorageBackend |
İki arka ucu da sarar | Kaydedilen her nesneyi depolama anahtarını ilişkili veri olarak kullanıp AES-256-GCM ile mühürler; eski düz metin nesneleri değiştirmeden okur | src/cluster_erp/core/storage.py:138-174 |
create_storage_backend, storage_backend s3 ise S3'ü, değilse yerel depolamayı seçer. storage_encryption_key ayarlıysa sonucu EncryptedStorageBackend ile sarar, değilse bir uyarı yazar (src/cluster_erp/core/storage.py:177-209). Ayar doğrulayıcısı anahtarı çok kiracılı kipte zorunlu kılar (src/cluster_erp/config/settings.py:805-809). Anahtar yönetimi ikinci faktör ve gizli depolama sayfasında belgelenir.
Kısıtlar ve doğrulama¶
- Bir ek satırı ve dosyası aynı istekte yazılır; dosya satır flush edilmeden önce kaydedilir (
src/cluster_erp/core/attachments.py:126-142). - Bir eki kullanımdan kaldırmak saklanan dosyayı silmez (
src/cluster_erp/core/attachments.py:155-161). Saklama süresinde dosyaların kaldırılmasırecordsmodülüne aittir; bkz. records.
Tanıtılan terimler¶
| Terim | Kod tanımlayıcısı | Tanım | Türkçe terim | Kaynak |
|---|---|---|---|---|
| attachment | Attachment |
Varlık türü ve kimliğiyle herhangi bir kayda bağlanan dosya. | ek | src/cluster_erp/core/attachments.py:51 |
| note | Note |
Varlık türü ve kimliğiyle herhangi bir kayda bağlanan metin notu. | not | src/cluster_erp/core/notes.py:17 |
| storage backend | StorageBackend |
Dosya baytlarını anahtarla kaydeden ve yükleyen arayüz. | depolama arka ucu | src/cluster_erp/core/storage.py:11 |
İlgili sayfalar¶
- Platform çekirdeği
- Ortak sunucu rotaları
- Ayarlar başvurusu
- Kayıt belgeleri, görüntüleyici ve paylaşım
92f8051 numaralı commit ile 2026-11-13 tarihinde doğrulandı.