From f115fed5a656f7c9f86159b546d7bc25e51e83cd Mon Sep 17 00:00:00 2001 From: Edouard Vanbelle Date: Fri, 3 Jul 2026 23:52:31 +0200 Subject: [PATCH] feat(drive): cleanup of useless owner_id --- .../services/file_upload_service.rs | 2 - src/domain/entities/file.rs | 22 ------ src/domain/entities/folder.rs | 77 ++----------------- .../pg/file_blob_read_repository.rs | 3 - .../pg/file_blob_write_repository.rs | 8 -- .../repositories/pg/folder_db_repository.rs | 6 -- 6 files changed, 7 insertions(+), 111 deletions(-) diff --git a/src/application/services/file_upload_service.rs b/src/application/services/file_upload_service.rs index 3218a5f3..37dba99b 100644 --- a/src/application/services/file_upload_service.rs +++ b/src/application/services/file_upload_service.rs @@ -296,7 +296,6 @@ impl FileUploadService { parts.folder_id, parts.created_at, updated_at as u64, - parts.owner_id, new_hash, ) .map_err(|e| DomainError::internal_error("FileUpload", format!("rebuild entity: {e}")))?; @@ -467,7 +466,6 @@ impl FileUploadUseCase for FileUploadService { parts.folder_id, parts.created_at, updated_at as u64, - parts.owner_id, new_hash, ) .map_err(|e| { diff --git a/src/domain/entities/file.rs b/src/domain/entities/file.rs index 9c9ba7ce..e4a65884 100644 --- a/src/domain/entities/file.rs +++ b/src/domain/entities/file.rs @@ -22,7 +22,6 @@ pub struct FileParts { pub folder_id: Option, pub created_at: u64, pub modified_at: u64, - pub owner_id: Option, /// BLAKE3 content hash. See [`File::content_hash`] for semantics. pub blob_hash: String, /// §14 provenance: original creator. See [`File::created_by`]. @@ -70,9 +69,6 @@ pub struct File { /// Last modification timestamp (seconds since UNIX epoch) modified_at: u64, - /// Owner user ID (from storage.files.user_id) - owner_id: Option, - /// BLAKE3 content hash. Stable across renames/moves, changes only /// when the file's content bytes change. Source of truth for both /// content-addressable storage and the HTTP ETag (via @@ -109,7 +105,6 @@ impl Default for File { folder_id: None, created_at: 0, modified_at: 0, - owner_id: None, blob_hash: String::new(), created_by: None, updated_by: None, @@ -150,7 +145,6 @@ impl File { folder_id, created_at: now, modified_at: now, - owner_id: None, blob_hash: String::new(), created_by: None, updated_by: None, @@ -184,7 +178,6 @@ impl File { folder_id: parent_id, created_at, modified_at, - owner_id: None, blob_hash: String::new(), created_by: None, updated_by: None, @@ -201,7 +194,6 @@ impl File { folder_id: Option, created_at: u64, modified_at: u64, - owner_id: Option, ) -> FileResult { Self::with_timestamps_and_blob_hash( id, @@ -212,7 +204,6 @@ impl File { folder_id, created_at, modified_at, - owner_id, String::new(), ) } @@ -227,7 +218,6 @@ impl File { folder_id: Option, created_at: u64, modified_at: u64, - owner_id: Option, blob_hash: String, ) -> FileResult { Self::with_timestamps_blob_hash_and_provenance( @@ -239,7 +229,6 @@ impl File { folder_id, created_at, modified_at, - owner_id, blob_hash, None, None, @@ -259,7 +248,6 @@ impl File { folder_id: Option, created_at: u64, modified_at: u64, - owner_id: Option, blob_hash: String, created_by: Option, updated_by: Option, @@ -282,7 +270,6 @@ impl File { folder_id, created_at, modified_at, - owner_id, blob_hash, created_by, updated_by, @@ -304,7 +291,6 @@ impl File { folder_id: self.folder_id, created_at: self.created_at, modified_at: self.modified_at, - owner_id: self.owner_id, blob_hash: self.blob_hash, created_by: self.created_by, updated_by: self.updated_by, @@ -407,10 +393,6 @@ impl File { self.modified_at } - pub fn owner_id(&self) -> Option { - self.owner_id - } - /// User that originally created this file (§14 provenance). /// `None` when the referenced user has been deleted /// (FK is `ON DELETE SET NULL`) or for stub/DTO entities. @@ -455,7 +437,6 @@ impl File { folder_id, created_at, modified_at, - owner_id: None, blob_hash: String::new(), // DTO round-trips don't carry provenance; callers needing // it must reload from the repository. @@ -607,7 +588,6 @@ mod tests { None, 1_000, 2_000, - None, "abcdef0123456789ZZZZZZZZ".to_string(), ) .unwrap(); @@ -632,7 +612,6 @@ mod tests { None, 1_000, 2_000, - None, "shorthash".to_string(), ) .unwrap(); @@ -655,7 +634,6 @@ mod tests { None, 1_000, 2_000, - None, "stable-content-hash".to_string(), ) .unwrap(); diff --git a/src/domain/entities/folder.rs b/src/domain/entities/folder.rs index 53242dc3..452609ae 100644 --- a/src/domain/entities/folder.rs +++ b/src/domain/entities/folder.rs @@ -25,10 +25,6 @@ pub struct Folder { /// Parent folder ID (None if it's a root folder) parent_id: Option, - /// Owner user ID — scopes folder visibility per user. - /// `None` only for legacy/stub folders; real folders always have an owner. - owner_id: Option, - /// Drive that owns this folder. Post-D0 every `storage.folders` row /// has `drive_id NOT NULL` (M3 migration). Path-based lookups scope /// by this axis (not by `user_id`, which is dropped in D7). @@ -76,7 +72,6 @@ impl Default for Folder { storage_path: StoragePath::from_string("/"), path_string: "/".to_string(), parent_id: None, - owner_id: None, drive_id: Uuid::nil(), created_at: 0, modified_at: 0, @@ -88,26 +83,20 @@ impl Default for Folder { } impl Folder { - /// Creates a new folder with validation + /// Creates a new folder with validation. + /// + /// In-memory constructor: callers that don't supply a `drive_id` + /// are by definition stub/legacy paths (tests, pre-D0 fixtures, + /// DTO round-trips). Real DB-backed folders flow through + /// [`Folder::with_timestamps_and_tree`] which propagates the + /// drive scope and §14 provenance from the row. pub fn new( id: String, name: String, storage_path: StoragePath, parent_id: Option, - ) -> FolderResult { - Self::new_with_owner(id, name, storage_path, parent_id, None) - } - - /// Creates a new folder with validation and an explicit owner. - pub fn new_with_owner( - id: String, - name: String, - storage_path: StoragePath, - parent_id: Option, - owner_id: Option, ) -> FolderResult { let name = normalize_storage_name(&name); - // Validate folder name if let Err(reason) = validate_storage_name(&name) { return Err(FolderError::InvalidFolderName(format!("{name}: {reason}"))); } @@ -117,7 +106,6 @@ impl Folder { .unwrap_or_default() .as_secs(); - // Store the path string for serialization compatibility let path_string = storage_path.to_string(); Ok(Self { @@ -126,17 +114,10 @@ impl Folder { storage_path, path_string, parent_id, - owner_id, - // In-memory constructor: callers that don't supply a - // drive_id are by definition stub/legacy paths (tests, - // pre-D0 fixtures, DTO round-trips). Real DB-backed - // folders flow through `with_timestamps_and_tree`. drive_id: Uuid::nil(), created_at: now, modified_at: now, tree_modified_at: now, - // Provenance is unknown for in-memory construction; the DB - // reconstruction path supplies real values. created_by: None, updated_by: None, }) @@ -160,34 +141,6 @@ impl Folder { name, storage_path, parent_id, - None, - Uuid::nil(), - created_at, - modified_at, - modified_at, - ) - } - - /// Creates a folder with specific timestamps and owner (legacy - /// constructor — `tree_modified_at` defaults to `modified_at`). - /// Prefer [`Folder::with_timestamps_and_tree`] for DB reconstruction - /// so the rollup ETag reflects descendant activity, not just this - /// row's own metadata. - pub fn with_timestamps_and_owner( - id: String, - name: String, - storage_path: StoragePath, - parent_id: Option, - owner_id: Option, - created_at: u64, - modified_at: u64, - ) -> FolderResult { - Self::with_timestamps_and_tree( - id, - name, - storage_path, - parent_id, - owner_id, Uuid::nil(), created_at, modified_at, @@ -209,7 +162,6 @@ impl Folder { name: String, storage_path: StoragePath, parent_id: Option, - owner_id: Option, drive_id: Uuid, created_at: u64, modified_at: u64, @@ -220,7 +172,6 @@ impl Folder { name, storage_path, parent_id, - owner_id, drive_id, created_at, modified_at, @@ -239,7 +190,6 @@ impl Folder { name: String, storage_path: StoragePath, parent_id: Option, - owner_id: Option, drive_id: Uuid, created_at: u64, modified_at: u64, @@ -260,7 +210,6 @@ impl Folder { storage_path, path_string, parent_id, - owner_id, drive_id, created_at, modified_at, @@ -299,10 +248,6 @@ impl Folder { self.modified_at } - pub fn owner_id(&self) -> Option { - self.owner_id - } - /// Drive that owns this folder. Path-based lookups scope by /// this axis (post-D0 invariant: `storage.folders.drive_id` /// is `NOT NULL`). @@ -412,7 +357,6 @@ impl Folder { storage_path, path_string: path, parent_id, - owner_id: None, // DTO round-trips lose drive_id (FolderDto carries it, // but the legacy `from_dto` signature predates this // change). Callers that need real scoping must reload @@ -460,7 +404,6 @@ impl Folder { storage_path: new_storage_path, path_string: new_path_string, parent_id: self.parent_id.clone(), - owner_id: self.owner_id, drive_id: self.drive_id, created_at: self.created_at, modified_at: now, @@ -501,7 +444,6 @@ impl Folder { storage_path: new_storage_path, path_string: new_path_string, parent_id, - owner_id: self.owner_id, drive_id: self.drive_id, created_at: self.created_at, modified_at: now, @@ -593,7 +535,6 @@ mod tests { "folder".to_string(), StoragePath::from_string("/folder"), None, - None, Uuid::nil(), 1_000, 2_000, @@ -615,7 +556,6 @@ mod tests { "a".to_string(), StoragePath::from_string("/a"), None, - None, Uuid::nil(), 0, 0, @@ -627,7 +567,6 @@ mod tests { "b".to_string(), StoragePath::from_string("/b"), None, - None, Uuid::nil(), 0, 0, @@ -650,7 +589,6 @@ mod tests { "folder".to_string(), StoragePath::from_string("/folder"), None, - None, Uuid::nil(), 1_000, 2_000, @@ -662,7 +600,6 @@ mod tests { "folder".to_string(), StoragePath::from_string("/folder"), None, - None, Uuid::nil(), 1_000, 2_000, diff --git a/src/infrastructure/repositories/pg/file_blob_read_repository.rs b/src/infrastructure/repositories/pg/file_blob_read_repository.rs index 0aa2ea83..2de4393e 100644 --- a/src/infrastructure/repositories/pg/file_blob_read_repository.rs +++ b/src/infrastructure/repositories/pg/file_blob_read_repository.rs @@ -397,8 +397,6 @@ impl FileBlobReadRepository { } } - /// Post-D7-step-6: `storage.files.user_id` dropped; the entity's - /// legacy `user_id` field is populated with `None` here. #[allow(clippy::too_many_arguments)] fn row_to_file( id: String, @@ -423,7 +421,6 @@ impl FileBlobReadRepository { folder_id, created_at as u64, modified_at as u64, - None, // Post-D7: `files.user_id` column dropped. blob_hash, created_by, updated_by, diff --git a/src/infrastructure/repositories/pg/file_blob_write_repository.rs b/src/infrastructure/repositories/pg/file_blob_write_repository.rs index 3de28382..e77be731 100644 --- a/src/infrastructure/repositories/pg/file_blob_write_repository.rs +++ b/src/infrastructure/repositories/pg/file_blob_write_repository.rs @@ -104,7 +104,6 @@ impl FileBlobWriteRepository { mime_type: String, created_at: i64, modified_at: i64, - owner_id: Option, blob_hash: String, created_by: Option, updated_by: Option, @@ -119,7 +118,6 @@ impl FileBlobWriteRepository { folder_id, created_at as u64, modified_at as u64, - owner_id, blob_hash, created_by, updated_by, @@ -399,7 +397,6 @@ impl FileBlobWriteRepository { content_type, created_at, updated_at, - None, // Post-D7: `files.user_id` no longer written on new rows. blob_hash.to_string(), created_by, updated_by, @@ -477,7 +474,6 @@ impl FileBlobWriteRepository { mime_type, created_at, updated_at, - None, blob_hash.to_string(), created_by, updated_by, @@ -562,7 +558,6 @@ impl FileWritePort for FileBlobWriteRepository { row.4, row.5, row.6, - None, String::new(), row.7, row.8, @@ -710,7 +705,6 @@ impl FileWritePort for FileBlobWriteRepository { row.4, row.5, row.6, - None, row.7, row.8, row.9, @@ -773,7 +767,6 @@ impl FileWritePort for FileBlobWriteRepository { row.4, row.5, row.6, - None, String::new(), row.7, row.8, @@ -874,7 +867,6 @@ impl FileWritePort for FileBlobWriteRepository { content_type, row.1, row.2, - None, // Post-D7: `files.user_id` no longer written on new rows. String::new(), row.3, row.4, diff --git a/src/infrastructure/repositories/pg/folder_db_repository.rs b/src/infrastructure/repositories/pg/folder_db_repository.rs index 7cd92f8a..4dc65f9d 100644 --- a/src/infrastructure/repositories/pg/folder_db_repository.rs +++ b/src/infrastructure/repositories/pg/folder_db_repository.rs @@ -129,11 +129,6 @@ impl FolderDbRepository { /// extra queries needed. `created_by` / `updated_by` carry the /// §14 provenance signal through the entity layer; both are /// `Option` because the FK is `ON DELETE SET NULL`. - /// - /// Post-D7-step-6: the `storage.folders.user_id` column is gone; - /// the entity's legacy `user_id` field is populated with `None` - /// at construction time (removed in the follow-up entity - /// cleanup PR). #[allow(clippy::too_many_arguments)] fn row_to_folder( id: String, @@ -153,7 +148,6 @@ impl FolderDbRepository { name, storage_path, parent_id, - None, // Post-D7: `folders.user_id` column dropped. drive_id, created_at as u64, modified_at as u64,