Commit Graph

12 Commits

Author SHA1 Message Date
Edouard Vanbelle 583af517c2 fix(drive): fix drive_id on copy to other drive
- fix alsot drive_id exposition
2026-06-29 23:21:17 +02:00
Claude 8dab135090 Add embedded Tantivy full-text content search
/api/search now finds files by CONTENT as well as by name: BM25-ranked
matches over extracted text (PDF, Office OOXML/ODF, plain text/code)
with typo-tolerant fuzzy terms and search-as-you-type prefix matching,
served from an embedded Tantivy index at {storage}/.search-index.

Pipeline (all off the request path, mirroring tree-etag + thumbnails):
- statement triggers on storage.files append to a durable dirty queue
  (storage.search_index_dirty) - every write surface (REST, WebDAV,
  NextCloud, WOPI, trash) is covered, crash-safe by construction
- ContentIndexWorker drains the queue on the maintenance pool, extracts
  text once per unique BLAKE3 blob (storage.blob_extracted_text cache:
  N copies = 1 extraction, renames/moves = 0 re-extraction) and applies
  batched single-writer Tantivy commits; queue rows are deleted only
  after the commit succeeds (at-least-once, idempotent upserts)
- the index is a derived artifact: a version-marker mismatch wipes and
  reseeds it from Postgres, which remains the single source of truth

SearchService merges content hits into the existing name search: hits
are hydrated through ONE SQL round-trip that re-applies user scope,
trash state and every active filter (a stale index id can never leak),
scored below name matches, and returned with a plain-text snippet and
a match_source field. Index failure or
OXICLOUD_ENABLE_CONTENT_SEARCH=false degrades to name-only search; a
discard-only janitor keeps the trigger-fed queue bounded while disabled.

The frontend renders the snippet under the file name in list view.

New dependencies: tantivy 0.26, zip 8.6 (deflate only), pdf-extract 0.10.

https://claude.ai/code/session_01Sc7F4xbo83YbFAQ4xEeDrX
2026-06-11 15:16:03 +00:00
Edouard Vanbelle bde7c83932 feat(content_hash): propagate etag and hash_content to */resources 2026-06-06 20:11:13 +02:00
Edouard Vanbelle badf35f08f chore: remove all executable attributes on non bash files 2026-04-01 23:14:42 +02:00
iltumio bf7e030cd6 feat: add OpenAPI spec generation with utoipa and justfile
- Add utoipa v5 dependency with ToSchema derives on all REST API DTOs
- Annotate free-function handlers with #[utoipa::path] (trash, share, favorites, recent)
- Create ApiDoc struct with OpenApi derive registering 37 schemas across 7 tags
- Add generate-openapi binary outputting resources/gen/openapi.json
- Serve OpenAPI spec at GET /api/openapi.json (public, no auth)
- Add justfile with common dev commands (build, test, lint, check, openapi, db)
2026-03-29 18:49:10 +02:00
Dionisio f2d35ca792 feat: auto-persist JWT secret, remove setup token requirement
- JWT secret auto-generates and persists to <STORAGE_PATH>/.jwt_secret
- Remove setup token: first admin setup is open until system initialized
- Fix schema.sql: move CREATE EXTENSION pg_trgm/ltree to top
- Update login UI and auth.js to remove setup token fields
2026-03-05 22:12:53 +01:00
Dionisio 5b55056921 perf: Arc-wrap SearchResultsDto for zero-copy cache reads
- Change SearchUseCase::search() return type to Arc<SearchResultsDto>
- Replace Cache<u64, SearchResultsDto> with Cache<u64, Arc<SearchResultsDto>>
- Eliminate .clone() on full result set; use Arc::clone() (ptr bump)
- Remove Clone derive from SearchResultsDto (no longer needed)
- Update handlers to deref Arc for JSON serialization
2026-02-25 23:47:51 +01:00
Diocrafts b501c4052b perf: replace recursive spawn-per-folder search with O(1) ltree queries
- Add search_files_in_subtree() to FileReadPort with ltree-based SQL
- Add list_descendant_folders() to FolderRepository with ltree GiST index
- Implement both in PG repositories (single query per entity type)
- Remove search_parallel() fan-out (O(N) tokio::spawn → 0 spawns)
- Remove passes_file_filter/passes_folder_filter (filtering now in SQL)
- Fix SearchCriteriaDto cache key: JSON serialization → u64 hash (15x faster)
- Fix escaped quote literals in webdav_handler.rs handle_put function
2026-02-23 00:17:40 +01:00
Diocrafts 0d7c8bc019 perf: optimize UI rendering and event lifecycle 2026-02-18 10:53:43 +01:00
Dionisio 7737ed90c7 feat: folder ownership scoping, batch operations integration, frontend audit fixes
Backend:
- Add owner_id to Folder entity + FolderDto (DB user_id column)
- Add list_folders_by_owner to FolderRepository trait + PG impl
- Add list_folders_for_owner to FolderUseCase + FolderService
- Rewrite FolderHandler: all endpoints now scope by AuthUser
- Remove dead handler methods (list_folders_inner, list_folders_for_user, is_user_home_folder, folder_belongs_to_user)
- Add ownership check in get_folder (returns 404 on mismatch)

Batch operations:
- Add trash_service + zip_service to BatchOperationService
- New methods: trash_files, trash_folders, move_folders, download_zip
- New handlers: trash_batch, move_folders_batch, download_batch
- New routes: POST /api/batch/trash, /api/batch/folders/move, /api/batch/download

Frontend:
- Replace findUserHomeFolder (~130 lines) with resolveHomeFolder (~35 lines)
- Remove client-side folder filtering in loadFiles (backend now scopes)
- Rewrite batchDelete: N requests -> 1 POST /api/batch/trash
- Rewrite batchMove: N requests -> 2 POST max (files + folders)
- Rewrite batchDownload: N requests -> 1 POST /api/batch/download (ZIP)
- Search moved to backend, share system uses backend API
- Dark mode fixes, frontend audit improvements
2026-02-15 23:45:11 +01:00
Dionisio 4c98c5a657 style: apply cargo fmt to entire codebase
Standardize code formatting across all 173 Rust source files
using rustfmt. No functional changes - purely cosmetic.

This establishes a consistent code style baseline for the
project going forward.
2026-02-14 01:29:34 +01:00
DioCrafts 7affff379d adding search engine 2025-03-27 01:13:34 +01:00