Skip to content

Workspace-level storage isolation & attachment cleanup#17

Merged
TechHutTV merged 4 commits into
mainfrom
feat/storage-scheme
Mar 2, 2026
Merged

Workspace-level storage isolation & attachment cleanup#17
TechHutTV merged 4 commits into
mainfrom
feat/storage-scheme

Conversation

@TechHutTV
Copy link
Copy Markdown
Contributor

@TechHutTV TechHutTV commented Mar 1, 2026

Summary

  • Workspace-scoped storage: All file writes (drive files, uploads, avatars, wiki images, backup imports) are now nested under {workspaceId}/ on disk, enabling per-workspace management, cleanup, and data export.
  • Remove direct attachment uploads: The separate attachment upload endpoint and its storage scheme (attachments/ category) are removed. Attachments now exclusively link to Drive files — no more dual storage path.
  • Remove dead upload fallback: The "general" purpose fallback in the upload controller is gone. Uploads now require an explicit workspaceId and a valid purpose (avatar or wiki), otherwise they're rejected.
  • Flatten storage paths: The YYYY/MM date-based subdirectories in buildPath are removed. Files are stored directly under their scope directory.
  • Backward compatibility: Legacy static routes (/storage/avatars/, /storage/uploads/, /uploads/) remain so existing files still resolve. A new /storage/:workspaceId/uploads/* route serves workspace-scoped uploads.

New storage structure

storage/
└── {workspaceId}/
    ├── files/
    │   ├── {userId}/{fileId}.ext
    │   └── groupfolders/{teamFolderId}/{fileId}.ext
    └── uploads/
        ├── avatars/{userId}/{fileId}.ext
        └── wiki/
            ├── {spaceId}/{fileId}.ext
            └── imports/{fileId}.ext

Changes

Backend

  • uploads.controller.ts — Require workspaceId and purpose from form data, use {workspaceId}/uploads as storage category, remove general fallback
  • files.service.ts — Use {workspaceId}/files category in uploadFileStream and copyFile
  • restore.service.ts — Use {workspaceId}/uploads category for re-uploaded assets, remove attachment restore logic
  • storage.ts — Remove YYYY/MM date directories from buildPath
  • static.ts — Add /storage/:workspaceId/uploads/* route via reply.sendFile(), enable decorateReply on first registration
  • attachments.controller.ts — Remove uploadAttachmentHandler and direct-upload storage delete
  • attachments.service.ts — Remove uploadAttachmentStream, simplify download to use linked Drive file only
  • attachments.routes.ts — Remove POST /workspaces/:wid/attachments route
  • backup.service.ts — Remove attachment file export logic, drop attachments/ from ZIP parsing
  • backup.controller.ts — Remove attachments/ prefix from ZIP entry extraction

Frontend

  • uploads/api.ts — Add required workspaceId and optional spaceId to UploadInput, send in form data
  • wiki-editor.tsx — Accept optional workspaceId and spaceId props, send in upload form data
  • wiki-page-view.tsx — Accept and pass workspaceId to WikiEditor
  • knowledge.tsx — Pass workspace.id to WikiPageView
  • topbar.tsx — Pass workspaceId in avatar upload call with guard
  • profile-settings.tsx — Resolve workspaceId from route params, pass in avatar upload call with guard
  • backup-settings.tsx — Remove attachment count from restore summary, update include-files label

Shared

  • attachment.ts — Remove CreateAttachmentSchema (no longer used)
  • backup.ts — Remove attachments from RestoreSummary

@TechHutTV TechHutTV changed the title Storage schemes Workspace-level storage isolation & attachment cleanup Mar 2, 2026
@TechHutTV TechHutTV merged commit 5f9b9b4 into main Mar 2, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant