Skip to content
This repository was archived by the owner on Jul 3, 2026. It is now read-only.

feat: redone Framework integration - #604

Merged
safwansamsudeen merged 56 commits into
developfrom
ff-file
Jun 8, 2026
Merged

feat: redone Framework integration#604
safwansamsudeen merged 56 commits into
developfrom
ff-file

Conversation

@safwansamsudeen

@safwansamsudeen safwansamsudeen commented Mar 4, 2026

Copy link
Copy Markdown
Contributor

Drive’s entity model moves from a parallel Drive File doctype onto Frappe’s framework File, extended with Drive custom fields and a subclass override. One row type powers the SPA, desk attachments, Writer documents, presentations, and S3/disk storage.


Why

  • One source of truth — listings, permissions, trash, and desk attachments all read the same File rows.
  • Framework integration — stock upload/attach flows can route through Drive without a shadow doctype.
  • Clearer semantics — explicit kind and content_doctype replace overlapping modifiable / is_attachment flags.

This is a breaking migration. Sites with existing Drive data must run bench migrate before using the new frontend.


Architecture

flowchart LR
  subgraph before [Before]
    DF[Drive File]
    DD[Drive Document]
    DF --> DD
  end

  subgraph after [After]
    FF[framework File]
    WD[Writer Document]
    PR[Presentation]
    FF -->|content_doctype| WD
    FF -->|content_doctype| PR
    FF -->|content_doctype File| LIB[library File ref]
  end

  before -->|integrate_with_framework| after
Loading

Framework File custom fields

Field Purpose
team Drive team scope (null = site / framework file)
status Active / Trashed / Removed (tombstone before hard delete)
file_modified User-visible “modified” without touching framework modified
mime_type Drive MIME (framework field is unreliable for our blobs)
content_doctype / content_docname Backing record — Writer Document, Presentation, or another File (attachment ref)

Listing kind (replaces modifiable / is_attachment)

Every Drive listing row carries exactly one kind:

kind Meaning Rename / move / share
native Drive-managed team file
readonly Shown in Drive but not managed here
virtual Fabricated Doctype→Doc grouping node (not a DB row)

readonly sub-cases use existing fields — no extra kind values:

  • !team → site / framework file → “Open in Desk”
  • content_doctype === "File" → attachment ref → “Go to original”

Frontend uses isManaged / isReadonly / isVirtual for gates, and isSiteFile / isAttachmentRef for the two readonly actions (GenericPage, Navbar, InfoPopup).

This delineation will be removed in a follow up PR, and all files will be editable through Drive.

drive.overrides.file.File

Team-scoped files use a File subclass for Drive behavior:

  • Lifecycleafter_insert (activity log), after_delete (cascade folders, related rows, backing content doc), on_rollback (upload cleanup)
  • Operationsmove, rename, share, unshare, permanent_delete, toggle_favourite
  • Guardsis_private enforced in validate; desk rename blocked unless via Drive UI (flags.drive_disk_rename)
  • Disk — skip path moves when _not_in_disk() (Link, empty file_url, or any content_doctype)

has_permission on "File" delegates to Drive ACLs; site files fall through to framework permissions.


Migration

Patch: drive.patches.integrate_with_framework (pre_model_sync)

  1. Reads legacy tabDrive File (if it still exists)
  2. Inserts matching framework File rows (same IDs via _name)
  3. Maps content_doctype / content_docname for Writer docs & presentations
  4. Sets frappe.flags.mute_drive_activity_log so bulk insert doesn’t spam activity logs

After migrate, legacy Drive File tables can be dropped when the doctype is removed from code.

Upgrade path: deploy → bench migrate → verify listings → remove Drive File doctype in a follow-up.

Fresh install: patch no-ops (no legacy table); custom fields sync via fixtures.


Desk integration

  • Library tab → Drive picker (drive/public/js/ff_integration.bundle.js, FileUploader.vue)
    • Site / Home / Teams tabs, folder navigation, infinite scroll, search
    • Attach existing file or upload into a chosen Drive folder
  • after_upload_file — when “use Drive for files” is on, framework uploads land in the user’s personal Drive home (with safe fallback when no personal team exists)

Removed / deprecated doctypes

Removed Replaced by
Drive File framework File (+ override) — doctype folder still present until B1 cleanup lands
Drive Document Writer Document (Writer app)
Drive Comment, Drive Doc Version, Drive Document Version Writer / activity model
Drive Disk Settings consolidated elsewhere
Drive Tag / Drive Entity Tag / tags API dropped in this branch
Drive Desktop Client dropped

Notable fixes

  • S3storage_key() centralizes key derivation; s3.fetch serves through get_file_content with uniform 404 (no guest enumeration)
  • Trashclear_deleted_files date math; status Select instead of magic ints
  • Permissionshas_permission on "File"; stricter move/unshare checks
  • List API — bounded share-count queries; share_count priority collision fixed
  • Upload — embed path typo (file_name); sync_from_disk file_type fix
  • Activity — move events logged; create events on insert
  • Presentation sync — hooks use File + content_docname, not Drive File

Frontend & toolchain (bundled)

This PR also ships formatting/tooling churn from the long-lived branch.

  • pnpm → yarn, Vite 4 → 8, frappe-ui as npm dependency
  • Prettier pass across frontend
  • kind-based UI gates (native / readonly / virtual); field-based readonly actions
  • Writer routes redirect to /writer/w/ (legacy Document.vue removed)

Upgrade commands

# backup first
bench --site <site> backup

# deploy ff-file, then:
bench --site <site> migrate
bench build --app drive

If migration reports failures, check integrate_with_framework output for file names that failed to insert.

@safwansamsudeen

Copy link
Copy Markdown
Contributor Author

@federicocalvo @nilpatel42 please let me know if you're interested in alpha testing 😄 (DM @realsafwan).

@federicocalvo

Copy link
Copy Markdown

This should be a real game-changer in terms of encouraging the use of the drive

safwansamsudeen and others added 18 commits May 26, 2026 14:39
…th (D1)

Notable decisions:
- Took ff-file's framework File doctype model throughout (file_name/is_folder/
  file_url over Drive File's title/is_group)
- Adopted develop's structured frappe.local.response.errors pattern in
  get_entity_with_permissions
- Adopted develop's delayedLoading watcher in DriveToolBar
- Adopted develop's Tooltip wrappers for share_count icons in ListView
- Kept ff-file's reactive storage-bar watch over develop's one-shot fetch
- Dropped DocEditor (deleted in develop) and the editor-style imports in
  utils/files.js and utils/download.js
- Took yarn over pnpm and frappe-ui npm 0.1.269 over the github pinned commit
- Switched newExternal Presentation flow to develop's /slides/presentation/new
  redirect; drive.api.files.create_presentation is now unreachable
- Restored develop's frappe_doc/markdown branch in getLink (was missing in HEAD)

D1: scripts.clear_deleted_files used today + timedelta(30); flipped to today -
    timedelta(30) so the job preserves status=-1 records for 30 days before
    hard-delete instead of nuking them on first run.
Resolving conflicts from develop's 33 commits since the last merge
(aa48b74). Same overall policy: ff-file owns the framework File doctype
model; develop wins on UI cleanups and removed/replaced features.

Notable decisions:
- Adopted develop's "track visit separately" pattern (6b3a972): dropped
  mark_as_viewed from get_entity_with_permissions, kept the standalone
  track_visit endpoint, and File.vue calls it on load.
- Did NOT re-add develop's markdown rendering block in permissions.py —
  ff-file 90f3878 deliberately removed it.
- Dropped develop's create_file / create_document_entity (Drive File
  doctype, unused) and create_presentation (newExternal routes directly
  to /slides/presentation/new, endpoint unreachable).
- Took develop's editor-frontend removal through: dropped printDoc,
  getPdfFromDoc, globalStyle/lowlight imports. Drive no longer supports
  downloading docs from the list view — folder downloads skip them
  silently rather than crash on the removed getPdfFromDoc.
- Switched presentation thumbnails to develop's get_presentation_thumbnail.
- Took develop's Signup.vue route + Dummy redirect for /w/:entityName
  (LoginSignup.vue and Document.vue both deleted in develop). Updated
  ErrorPage redirect and router fallback to external /login via
  window.location.href.
- Renamed Slides → Presentations everywhere (Sidebar label, router name).
- Took develop's view-aware getThumbnailUrl (list shows icon, grid shows
  thumbnail) — GridItem already passes view="grid".
- Kept ff-file's reactive storage-bar watch over develop's one-shot fetch.
- Kept ff-file's Home/Shared toggle on Personal.vue (intentional UX
  consolidation); develop's with/by tabs on /shared not applicable here.

Follow-ups not addressed:
- DriveToolBar Type sort field auto-merged to mime_type (was file_type);
  verify expected behavior.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- s3.fetch now serves through get_file_content (enforces Drive perms per
  request) instead of redirecting to it, and returns a uniform 404 for
  missing/forbidden so keys can't be enumerated
- rename sanitize_url -> storage_key; it always returns a relative key so
  `Path(base) / key` can't reset to an absolute path
- route every S3 Key/CopySource and site_folder join through storage_key,
  fixing move/move_to_trash passing the stored file_url as the S3 key
- normalize both ends of FileManager.move so any caller (rename, restore,
  desk move) resolves to the real backend key
- fix embed path typo entity.file_names -> file_name
- replace print() with frappe.log_error and narrow except in get_file
- add invariant test for storage_key/get_s3_url round-trip

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- File.status Int (1/0/-1) -> Select (Active/Trashed/Removed), backed by
  STATUS_ACTIVE/TRASHED/REMOVED constants; replace all numeric comparisons
  (incl. the `if doc.status:` truthiness trap in the trash toggle)
- rename details_doctype/details_docname -> content_doctype/content_docname
  (the record holding the file's actual content) in the fixture + all sites
- fix integrate_with_framework patch to write the real field names
  (file_modified, content_doctype/_docname) and the Select status value (D2)
- update ff-file-review.md: mark C1, C2, D2, D4, D7 resolved

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fix: incorrect bulk rename of file_name to title (hail ai)
@safwansamsudeen
safwansamsudeen marked this pull request as ready for review June 8, 2026 07:27
@safwansamsudeen
safwansamsudeen merged commit 10c3997 into develop Jun 8, 2026
1 check passed
@safwansamsudeen
safwansamsudeen deleted the ff-file branch June 8, 2026 07:39
GursheenK pushed a commit to frappe/suite that referenced this pull request Jun 17, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants