Last updated: 2026-02-11
Phase 1A: Backend — COMPLETE
Item
Status
Notes
VMS Settings (Single DocType)
Done
R2 credentials, upload limits, allowed extensions
VMS Project DocType
Done
Naming series, status workflow, role-based permissions
VMS Asset DocType
Done
Optional project link (null = Inbox), category field, R2 key, thumbnail_url, review_token, folder link
Custom Roles (Video Manager)
Done
Single role for all VMS users, desk_access=0
R2 Integration (r2.py)
Done
Upload, view, download presigned URLs + delete
API Endpoints (api.py)
Done
Upload flow, view/download URLs, move asset, category update, R2 test, bucket usage, folder CRUD
Permission Queries (permissions.py)
Done
Role-based filtering
hooks.py
Done
after_install, permission_query_conditions, website_route_rules, doc_events
boto3 in pyproject.toml
Done
>=1.35.0
Phase 1B: Frontend Tooling + App Shell — COMPLETE
Item
Status
Notes
Tailwind CSS v4 + Vite plugin
Done
No separate config file — all in CSS + Vite plugin
shadcn/ui (base-maia style)
Done
Uses @base-ui/react (not Radix), render prop pattern
React Router v7
Done
Protected routes redirect to Frappe /login
Sonner toasts
Done
HugeIcons
Done
@hugeicons/react + @hugeicons/core-free-icons
AppLayout, Sidebar, Header
Done
TypeScript interfaces
Done
VMSProject, VMSAsset, API response types
Phase 2: Core Upload, Browse & Inbox Workflow — COMPLETE
Item
Status
Notes
Dashboard Page
Done
Summary cards, recent projects, recent uploads
Projects Page
Done
Card grid, create project dialog, shadcn date picker (Issue #8)
Project Detail Page
Done
3-tab layout: All / For Review / Deliverables (Issue #23), list/grid toggle, bulk select
Inbox Page
Done
Unassigned assets, bulk select, bulk move/download, category badges
Upload Dialog + useUpload hook
Done
Drag-and-drop, category selector, concurrent uploads, per-file progress
Duplicate filename handling
Done
Inline conflict resolution UI with Skip/Rename per-file + bulk actions (Issue #10)
Retry failed uploads
Done
Re-attempt failed uploads without re-selecting files (Issue #9)
Page-level drop zone
Done
Entire project/inbox page is a drop target for uploads (Issue #18)
Move Asset Dialog
Done
Project picker dropdown, bulk move, toast confirmations
Media Player (Video/Audio/Image)
Done
Presigned view URLs, native HTML5 controls
Download (useDownload hook)
Done
Single + bulk download via presigned download URLs
Settings Dialog
Done
Two-pane layout, R2 config, upload settings, test connection
Dark Mode
Done
ThemeProvider + ModeToggle (Light/Dark/System), persists to localStorage
Phase 3: Thumbnail Generation — COMPLETE
Item
Status
Notes
thumbnails.py (FFmpeg + PIL)
Done
Videos: FFmpeg frame extraction at 1s; Images: PIL resize to 640px wide
Background job after confirm_upload
Done
Auto-enqueued via frappe.enqueue
Thumbnail storage
Done
Saved as public Frappe File attached to VMS Asset
Frontend asset card thumbnails
Done
Grid/list views render thumbnails with fallback icon
Phase 4: Video Review System — COMPLETE
Phase 4A: Core Review (Timestamped Comments)
Item
Status
Notes
VMS Review Comment DocType
Done
Naming: VMS-CMT-.#####, fields for timestamp, threading, annotations
Review API (review_api.py)
Done
9 endpoints: get_review_data, get_review_view_url, get/add/delete/resolve comments, annotation data, toggle public review, guest download
Review Page (/review/:assetId)
Done
Full-screen layout outside AppLayout, custom video player
Video Player + Controls
Done
Custom HTML5 controls, fullscreen, timeline markers
Timestamped Comments
Done
Click timestamp to seek, threaded replies, resolve/unresolve
Mobile responsive
Done
Comment input visible on mobile viewports (Issue #17)
Phase 4B: Drawing & Annotations (Fabric.js)
Item
Status
Notes
Fabric.js integration
Done
fabric v7.1.0
Drawing tools
Done
Arrow, freehand, line, rectangle, triangle + 6-color palette
Undo/redo
Done
Full undo/redo stack
Annotation storage
Done
JSON in annotation_data field, normalized 0-1 coordinates
Annotation replay
Done
Click drawing badge or timestamp to seek + render read-only overlay
Auto-capture on submit
Done
Submitting in annotation mode auto-captures canvas data
Phase 4C: Public Review Links & Guest Access
Item
Status
Notes
review_token field on VMS Asset
Done
Token-based access
Public review toggle
Done
toggle_public_review API
Guest commenting
Done
Via ?token= URL param, guest name field
Guest download
Done
get_guest_download_url endpoint
Phase 5: Folder System — COMPLETE (Issue #14)
Item
Status
Notes
VMS Folder DocType
Done
Naming: VMS-FLD-.#####, folder_name + project link
folder field on VMS Asset
Done
Optional link to VMS Folder
Backend APIs
Done
create_folder, rename_folder, delete_folder, move_assets_to_folder
Upload to folder
Done
get_upload_url accepts optional folder param
Frontend folder cards
Done
Grid + list views, breadcrumb navigation
Create / Rename / Delete folder
Done
Dialog UIs with validation
Move to Folder dialog
Done
Bulk move assets between folders
Drag-and-drop between folders
Done
Custom MIME type, drop targets on folder cards + breadcrumb
Scope
Done
1-level only (no nesting), folders in "All" tab only
Phase 6: Email Notifications — COMPLETE
Item
Status
Notes
Comment notification (notifications.py)
Done
Triggered via doc_events hook on VMS Review Comment after_insert
Notify asset uploader
Done
When someone else comments on their upload
Notify parent comment author
Done
When someone replies to their comment
Background processing
Done
frappe.enqueue (queue="short"), HTML-formatted emails
Phase 7: UX & Polish — COMPLETE
Item
Status
Notes
Skeleton/spinner loading states
Done
Throughout all pages and dialogs (Issue #5)
Cache user profile with SWR
Done
useFrappeGetDoc replaces manual POST fetch (Issue #6)
Calendar icon dark mode fix
Done
(Issue #7)
Navbar alignment fix
Done
(Issue #4)
Non-video files open in media dialog
Done
Instead of review editor (Issue #2)
Asset rename with audit logging
Done
2GB+ file upload support
Done
Long Int for file_size fields (Issue #11)
Phase 8: Testing & CI — COMPLETE
Item
Status
Notes
Playwright e2e setup
Done
Config, auth setup, test helpers for VMS/Frappe APIs
Project CRUD e2e tests
Done
projects.spec.ts
CI: Server tests workflow
Done
MariaDB + Redis, bench run-tests --app vms
CI: Linter workflow
Done
pre-commit, Semgrep security rules, pip-audit
CI: UI tests workflow
Done
Playwright + Chromium, artifact upload
MinIO for CI object storage
Done
End-to-end upload testing in CI
Item
Notes
Video Transcription
VMS Transcription DocType, provider integration, frontend panel
Version Tracking
Asset versioning
Transcript Search
Full-text search across transcriptions
E2E: Thumbnail generation test
Upload video, verify thumbnail generated (Issue #20)
DocType
Naming
Purpose
VMS Settings
Single
R2/Cloudflare config, upload limits
VMS Project
VMS-PRJ-.#####
Project container
VMS Asset
VMS-AST-.#####
Individual file/media asset
VMS Folder
VMS-FLD-.#####
1-level folder within project
VMS Review Comment
VMS-CMT-.#####
Timestamped review comments with annotations
VMS Audit Log
VMS-LOG-.#####
Action audit trail
shadcn base-maia style : Uses @base-ui/react instead of Radix. Components use render prop for composition (not asChild).
Tailwind CSS v4 : No tailwind.config.js — theme via CSS custom properties in index.css.
HugeIcons over Lucide : @hugeicons/react + @hugeicons/core-free-icons.
Asset categories : 3-category system — Asset, For Review, Deliverable — with matching tab layout.
frappe-react-sdk hooks throughout — SWR-based GET hooks, POST hooks for mutations.
Upload flow: get presigned URL → XHR PUT to R2 → confirm upload → thumbnail job.
Assets with project = null are "in the Inbox".
Fabric.js for annotation canvas with normalized coordinate storage.
Site: vms.localhost:8000
Frontend dev server: localhost:8080
R2 bucket: vms-media
Wrangler CLI for Cloudflare operations (npx wrangler)