mirror of
https://github.com/wekan/wekan.git
synced 2026-11-07 02:52:33 -05:00
- Migration importers: resolve the CollectionFS GridFS id from copies.<bucket>.key too (the REAL old-WeKan layout; only original.gridFsFileId / gridFsFileId / copies.gridfs.key were tried, none of which exist there) via a shared resolveCfsGridFsId() in releases/migrate-mongodb-to-ferretdb.mjs, snap-src/bin/migrate-mongo3-to-ferretdb.mjs and snap-src/bin/migrate-gridfs-to-fs.mjs. The modern importer now drives CollectionFS extraction from cfs_gridfs.<bucket>.files itself, so a missing/empty cfs.<bucket>.filerecord no longer silently skips every file; binaries without a filerecord are still extracted to disk, and filerecords whose binary cannot be located are reported on the dashboard instead of dropped. - Meteor-Files phase: match versions.*.meta.gridFsFileId without a storage flag (WeKan's own getFileStrategy rule), handle every version (not just 'original'), and add a bucket-driven sweep of <bucket>.files by metadata.fileId so binaries are recovered even when the record's flags say nothing about GridFS. GridFS-flagged versions with no locatable binary are reported. - mongo3 importer: copy the CollectionFS top-level boardId/cardId/ listId/swimlaneId/userId into meta on the created records - an attachment without meta.cardId shows on no card. - Admin Panel > Attachments: the Filesystem Storage paths were computed from process.env.WRITABLE_PATH IN THE BROWSER, so they always showed "/data". New admin-only getAttachmentStoragePaths method returns the real Snap-aware paths (shared models/lib/attachmentStoragePath.js), also used for the settings document default (was /data/attachments, actual Docker path is /data/files/attachments). - Snap: `snap run wekan.database ferretdb` now says it does NOT migrate data, says when nothing was switched, and points at `snap run wekan.migrate` for re-running the full migration. - Tests with negative cases: tests/migrationAttachmentExtraction.test.cjs (behavioral resolveCfsGridFsId from all three importers + wiring guards) and tests/attachmentStoragePath.test.cjs, wired into test:unit:node. - Companion fix in wekan/FerretDB: accept documents with literal dotted field names like MongoDB 3.6+, so migrated documents containing them are no longer silently dropped. - CHANGELOG.md: new Upcoming section with these changes. If attachments are already missing after an earlier migration, run `snap run wekan.migrate` - the source MongoDB data was never modified, and the fixed importers re-create the attachment records and files. Thanks to mueschel and xet7.
35 lines
1.6 KiB
JavaScript
35 lines
1.6 KiB
JavaScript
// Pure, dependency-free storage path computation (no Meteor imports) so it can
|
|
// be unit tested directly with plain Node. Used by the attachment storage
|
|
// settings (Admin Panel > Attachments) and kept in sync with the path logic in
|
|
// models/attachments.js, models/avatars.js and server/initializeDirs.js.
|
|
//
|
|
// #6473: the Admin Panel used to compute these paths ON THE CLIENT from
|
|
// process.env.WRITABLE_PATH, which never exists in a browser, so it always
|
|
// showed "/data" — a path that does not exist on a Snap install
|
|
// (WRITABLE_PATH=$SNAP_COMMON/files there). The real paths are:
|
|
// - Docker (WRITABLE_PATH=/data): /data/files/{attachments,avatars}
|
|
// - Snap (WRITABLE_PATH=$SNAP_COMMON/files): $SNAP_COMMON/files/{attachments,avatars}
|
|
// - Dev (WRITABLE_PATH unset): <cwd>/files/{attachments,avatars}
|
|
//
|
|
// Snap already appends '/files' to WRITABLE_PATH, so that case is detected and
|
|
// '/files' is not appended twice.
|
|
const path = require('path');
|
|
|
|
/**
|
|
* Compute the real attachment/avatar storage paths for a given base path.
|
|
* @param {string} [basePath] WRITABLE_PATH (falls back to process.cwd())
|
|
* @return {{writablePath: string, attachments: string, avatars: string}}
|
|
*/
|
|
function computeStoragePaths(basePath) {
|
|
const base = basePath || process.cwd();
|
|
const endsWithFiles = base.endsWith('/files') || base.endsWith('\\files');
|
|
const root = endsWithFiles ? base : path.join(base, 'files');
|
|
return {
|
|
writablePath: base,
|
|
attachments: path.join(root, 'attachments'),
|
|
avatars: path.join(root, 'avatars'),
|
|
};
|
|
}
|
|
|
|
module.exports = { computeStoragePaths };
|