Materials file-manager overhaul: nested folders, uploads, quota & AI ingestion - #11
Merged
Merged
Conversation
…ads, quota & AI ingestion Rework the module materials area into a proper file manager: - Nested folders: new material_folder table (self-referencing) + material.folderId, with migration + idempotent backfill from the legacy folder column. Sibling names kept unique via a COALESCE expression index. - Browser rewrite: breadcrumb navigation, list/grid toggle (persisted), multi-select (checkbox + ctrl/shift-click) with a bulk move/delete bar, per-folder and top-level stats, context menus on files AND folders, and drag & drop moves (files and folders). - Drag & drop upload of files and whole folders into the window (FileSystem Entry API with a flat fallback); folder structure is preserved server-side. - Zip upload is unpacked server-side (pg-boss job) into a same-named folder, preserving its tree; guards against zip-slip, __MACOSX and zip bombs; the archive is discarded after unpacking. - AI ingestion for all file types: extension-based routing adds DOCX (mammoth), PPTX/XLSX (OOXML scraping) and all code/text files; images run OCR/vision and audio/video run transcription via the configured provider. - Per-user storage quota: admin-configurable limit, enforced on upload, with a usage card in user settings. New server actions (createFolder, moveFolder, deleteFolder recursive/keep, bulk move/delete) plus helpers in lib/materials. Unit + DB integration tests cover folder trees, zip unpacking, path safety and file classification. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LWLUNyHYuCpouMEUo3P456
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reworks a module's Materials area from a flat, single-level list into a full file manager.
What's new
Folders & navigation
material_foldertable +material.folderId), replacing the old single-levelfoldertext column. Empty subfolders now persist.Selection & bulk actions
Ctrl/Cmd-click, andShift-range.Views & stats
Uploads
webkitdirectory) alongside file upload..ziparchives are unpacked server-side (background pg-boss job) into a same-named folder, preserving their internal tree. Guards against zip-slip,__MACOSX/dotfile cruft and zip bombs (entry-count + uncompressed-size caps). The archive is discarded after unpacking.AI can process all file types
extract.tsadds DOCX (mammoth), PPTX/XLSX (OOXML text scraping) and all code/plain-text files, on top of PDF.Storage quota (per user)
Data model & migration
0029createsmaterial_folder(self-referencing, cascade), addsmaterial.folder_id, and aCOALESCE(parent_id,'')unique index so sibling names stay unique even at the root.0030backfills the tree from the legacyfoldercolumn (idempotent). The old column is retained this release for rollback safety.Verification
__MACOSX), OOXML extraction and file-type classification.tsc --noEmit,eslint,vitest(79 passing) and a productionnext buildall green.New server actions (
createFolder,moveFolder,deleteFolder, bulk move/delete) and helpers live undersrc/lib/materials/. The DB-backed tests are gated behindRUN_DB_TESTS=1so CI without a database stays green.🤖 Generated with Claude Code
https://claude.ai/code/session_01LWLUNyHYuCpouMEUo3P456
Generated by Claude Code