feat(drive): cleanup of useless owner_id

This commit is contained in:
Edouard Vanbelle
2026-07-03 23:52:31 +02:00
parent 025045e4af
commit f115fed5a6
6 changed files with 7 additions and 111 deletions
@@ -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| {
-22
View File
@@ -22,7 +22,6 @@ pub struct FileParts {
pub folder_id: Option<String>,
pub created_at: u64,
pub modified_at: u64,
pub owner_id: Option<Uuid>,
/// 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<Uuid>,
/// 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<String>,
created_at: u64,
modified_at: u64,
owner_id: Option<Uuid>,
) -> FileResult<Self> {
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<String>,
created_at: u64,
modified_at: u64,
owner_id: Option<Uuid>,
blob_hash: String,
) -> FileResult<Self> {
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<String>,
created_at: u64,
modified_at: u64,
owner_id: Option<Uuid>,
blob_hash: String,
created_by: Option<Uuid>,
updated_by: Option<Uuid>,
@@ -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<Uuid> {
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();
+7 -70
View File
@@ -25,10 +25,6 @@ pub struct Folder {
/// Parent folder ID (None if it's a root folder)
parent_id: Option<String>,
/// Owner user ID — scopes folder visibility per user.
/// `None` only for legacy/stub folders; real folders always have an owner.
owner_id: Option<Uuid>,
/// 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<String>,
) -> FolderResult<Self> {
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<String>,
owner_id: Option<Uuid>,
) -> FolderResult<Self> {
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<String>,
owner_id: Option<Uuid>,
created_at: u64,
modified_at: u64,
) -> FolderResult<Self> {
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<String>,
owner_id: Option<Uuid>,
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<String>,
owner_id: Option<Uuid>,
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<Uuid> {
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,
@@ -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,
@@ -104,7 +104,6 @@ impl FileBlobWriteRepository {
mime_type: String,
created_at: i64,
modified_at: i64,
owner_id: Option<Uuid>,
blob_hash: String,
created_by: Option<Uuid>,
updated_by: Option<Uuid>,
@@ -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,
@@ -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<Uuid>` 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,