curo1305 and Claude Sonnet 4.6
b6911fb4ed
fix(12): resolve critical code review findings (CR-01 through CR-04)
...
- CR-01: fix browse URL from /folders/{id} to /items?parent_ref= (broken feature)
- CR-02: remove raw provider exception text from _TerminalProviderError messages
- CR-03: add user_id predicate to get_or_create_folder_state query (ownership boundary)
- CR-04: add max_length=255 to ConnectionRenameRequest.display_name
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-19 02:00:05 +02:00
curo1305
bf9af11274
feat(12-03): connection-ID routing, rename, session folder memory, thin views
...
- Route /cloud/:connectionId/:folderId replaces /cloud/:provider/:folderId
- api/cloud.js: getCloudFoldersByConnectionId + renameCloudConnection
- cloudConnections store: rename, selectConnection, setBrowseState, defaultDisplayName, session storage helpers
- CloudStorageView: thin — passes connectionRoots to StorageBrowser
- CloudFolderView: thin — uses connectionId param, never provider slug
- SettingsCloudTab: inline rename input for each active connection
- 27 tests pass: store, view, settings
2026-06-18 23:25:29 +02:00
curo1305
e97ca164d7
Refactor backend and frontend cleanup paths
2026-06-16 11:50:17 +02:00
curo1305 and Claude Sonnet 4.6
7ef65de046
refactor(09-05): CODE-09 purge — Phase 9 files (WHAT comments removed)
...
Frontend: AdminLayout, AdminSidebar, AdminOverviewView, AdminUsersView,
AdminQuotasView, AdminAiView, AdminAuditView, router/index.js, LoginView,
tailwind.config.js, api/admin.js — WHAT labels stripped; WHY constraints
preserved (D-16 anchors, security notes, api_key write-only invariant,
router guard rationale, D-08/D-09/D-10 decision refs, fetchWithRetry reason).
Backend: overview.py was already clean (no WHAT comments present).
Frontend: 137 tests pass, build succeeds.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-12 21:52:30 +02:00
curo1305
e6467d18cf
feat(09-04): delete AdminView + 4 tab files; update tests + router guard test
...
- git rm AdminView.vue, AdminUsersTab.vue, AdminQuotasTab.vue, AdminAiConfigTab.vue, AuditLogTab.vue
- Migrate tab tests to import from views/admin/Admin*View.vue
- Update router.guard.test.js: replace AdminView mock with AdminLayout + 5 admin view mocks
- Add D-09 redirect test (admin on / → /admin)
- Fix stale api/admin.js JSDoc consumer list
- Fix SettingsView.vue stale AdminView comment reference
2026-06-12 16:11:00 +02:00
curo1305
fd12ee2a22
feat(09-02): add getAdminOverview() to api/admin.js
...
- Export async function calling request('/api/admin/overview')
- Follows existing GET helper pattern (no extra wrapping)
- Auto-re-exported via client.js barrel (Phase 8 CODE-04 invariant preserved)
2026-06-12 15:46:00 +02:00
curo1305
02bf04cc63
feat(08-07): decompose frontend api/client.js into domain modules + utils — CODE-04 CODE-08
...
- Rewrite client.js as 20-line barrel re-export (was 636 lines)
- All 35+ consumer files continue to resolve named exports unchanged
- Fix pre-existing bug: testAiConnection was POST but tests expected GET with query params
- All 136 frontend tests pass; production build succeeds
2026-06-10 18:43:41 +02:00
curo1305
a895b1812f
feat(08-07): create domain modules admin.js, folders.js, shares.js, cloud.js — CODE-04
...
- admin.js: 17 functions; adminExportAuditLogCsv + adminDownloadDailyExport use fetchWithRetry
- folders.js: 6 functions — import request from utils.js
- shares.js: 5 functions — import request from utils.js
- cloud.js: 7 functions including initiateOAuth — import request from utils.js
- Blob-download retry boilerplate eliminated from admin.js (CODE-08)
2026-06-10 18:42:01 +02:00
curo1305
fd9188b53c
feat(08-07): create domain modules documents.js, auth.js, topics.js — CODE-04
...
- documents.js: 10 functions; fetchDocumentContent refactored to use fetchWithRetry
- auth.js: 15 functions (login through getMyQuota) — import request from utils.js
- topics.js: 5 functions — import request from utils.js
- All functions copied verbatim from client.js; no consumer files modified
2026-06-10 18:40:32 +02:00
curo1305
80d6f376b0
feat(08-07): create api/utils.js with request() and fetchWithRetry() — CODE-08
...
- Move request() verbatim from client.js to utils.js (breaks circular dep)
- Add fetchWithRetry() consolidating 3 blob-download 401-retry patterns
- Lazy import of authStore preserved for Pinia bootstrap cycle safety
- Bearer token from authStore memory only per CLAUDE.md security rule
2026-06-10 18:39:41 +02:00
curo1305 and Claude Sonnet 4.6
3b11b9a596
feat(07-uat): admin AI panel UX enhancements + DocumentCard status indicators
...
- GET /api/admin/ai-config/models — fetch model list from provider's /models endpoint
- POST /api/admin/ai-config/test-connection — replaced GET; accepts unsaved form
values (api_key, base_url, model_name) so admins can test before saving
- TestConnectionRequest Pydantic model with provider_id validation
- SearchableModelSelect.vue — new reusable combobox; Teleport to body avoids
overflow:hidden clipping; shows all models on open, filters only on typing;
static "Enter manually" item always pinned at bottom; caches per provider
- AdminAiConfigTab: model name input replaced with SearchableModelSelect;
testingProvider ref + spinner added to Test Connection button
- DocumentCard: processing spinner + "Classifying…", pending "Queued" badge,
classification_failed badge; topics section only shown when status=ready
- FileManagerView: onUnmounted imported (polling wiring pending next session)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-05 09:26:02 +02:00
curo1305
0db412d66c
feat(07-05): frontend AI config client helpers + AdminAiConfigTab system section + Vitest tests
...
- Add getAiConfig/saveAiConfig/testAiConnection to frontend/src/api/client.js
- AdminAiConfigTab.vue: add System AI Providers section above existing per-user table
- Per-provider accordion (10 providers from PROVIDER_DEFAULTS)
- Write-only API key field (never pre-filled), base URL, model, context_chars inputs
- Set Active (atomic flip), Save, Test Connection buttons with inline badges
- Existing per-user ai-config table and saveConfig logic untouched (Pitfall 6)
- Create frontend/tests/api.spec.js: 4 Vitest tests for getAiConfig/saveAiConfig/testAiConnection
- All 127 frontend tests pass, build exits 0 (D-11 frontend coverage)
2026-06-04 23:22:08 +02:00
curo1305
9e8f8d5bbc
fix(06.2): WR-06 use URLSearchParams in listShares for consistent encoding
2026-06-01 14:31:50 +02:00
curo1305
3fa7e8b866
fix(06.2): CR-04 WR-05 audit export functions use 401-refresh-retry and safe URL.revokeObjectURL
2026-06-01 14:26:05 +02:00
curo1305
0647e6e9bf
feat(06.2-04): frontend — user_handle filter, fetch+Blob export, daily-export section
...
- adminListAuditLog: rename user_id param to user_handle (backend API change)
- adminExportAuditLogCsv(): fetch+Blob pattern — sends Bearer header (D-13, T-06.2-04-03)
- adminListDailyExports(): raw fetch returning JSON for daily export listing (D-17)
- adminDownloadDailyExport(date): fetch+Blob download with audit-{date}.csv filename (D-17)
- AuditLogTab: rename filters.user_id to filters.user_handle + label 'User handle' (D-12, C-5)
- AuditLogTab: exportCsv() replaced with async fetch+Blob call, exportingCsv loading state
- AuditLogTab: daily exports section below pagination — date dropdown + Download button (D-17, C-4)
- window.location.href removed from AuditLogTab (broken auth bypass closed)
- Build exits 0, full backend suite: 337 passed, 1 pre-existing failure
2026-05-31 15:21:23 +02:00
curo1305 and Claude Sonnet 4.6
cce8586235
feat(06.2-03): frontend — CloudDeleteWarningModal + remove_only path in DocumentView
...
- api/client.js: deleteDocument gains removeOnly param; deleteDocumentRemoveOnly wrapper added
- DocumentView.vue: confirmDelete inspects response.cloud_delete_failed, shows modal on failure
- DocumentView.vue: inline CloudDeleteWarningModal (C-3 contract) with Remove from app / Cancel
- confirmRemoveOnly() calls DELETE ?remove_only=true and navigates to /
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 15:11:31 +02:00
curo1305 and Claude Sonnet 4.6
34b18a9f08
feat(06.2-02): frontend — is_shared badge fix + permission dropdown + View/Edit toggle
...
- DocumentCard.vue: fix Shared pill to read doc.is_shared (was doc.share_count > 0)
- ShareModal.vue: add permission select between handle input and submit button
- ShareModal.vue: replace static "view" span with View/Edit toggle group per share row
- ShareModal.vue: add handlePermissionChange with optimistic update + rollback on error
- documents.js: update shareDocument(docId, handle, permission='view') signature
- documents.js: add updateSharePermission(shareId, permission) action
- api/client.js: pass permission in createShare POST body
- api/client.js: add updateSharePermission PATCH helper
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 15:07:04 +02:00
curo1305 and Claude Sonnet 4.6
34f012b4e8
fix(05): resolve 5 critical code review findings
...
CR-01: add Field(min_length=1) to UserDeleteConfirm.admin_password
CR-02: add folder ownership check in PATCH /documents/{id} — prevents IDOR
when folder_id belongs to another user
CR-03: add min_length=1, max_length=255, and path-separator validator to
DocumentPatch.filename — prevents empty and path-traversal filenames
CR-04: fetchDocumentContent now throws on non-ok responses instead of
silently returning the error Response
CR-05: object URL revoke in DocumentView uses pagehide + load events with
120s fallback instead of unreliable 60s blind timer
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-30 11:51:54 +02:00
curo1305
72687212a1
feat(05-11): add adminDeleteUser API function + inline delete confirmation panel
...
- Export adminDeleteUser(id, adminPassword) from client.js — sends JSON body to DELETE /api/admin/users/{id}
- AdminUsersTab: add confirmDelete, deletePassword, deleteError state refs
- AdminUsersTab: add startDelete, cancelDelete, confirmDoDelete functions (mutually exclusive with deactivate panel)
- AdminUsersTab: Delete button added to active and deactivated user rows
- AdminUsersTab: inline password confirmation panel with Argon2 verification via backend
2026-05-30 11:39:10 +02:00
curo1305
87de148a59
feat(05-10): OAuth fetch + Nextcloud edit fix + Edit on ERROR + text overflow
...
- client.js: add initiateOAuth() and getConnectionConfig() helpers
- SettingsCloudTab: replace window.location.href with initiateOAuth() + fetch/JWT
- SettingsCloudTab: add Edit button to ACTIVE and ERROR blocks for non-OAuth providers
- SettingsCloudTab: wrap ConfirmBlock in w-full overflow-hidden div
- CloudCredentialModal: add existing prop, edit-mode pre-population via /config endpoint
- CloudCredentialModal: add showAdvanced + customEndpoint for Nextcloud custom paths
- ConfirmBlock: add break-words class to message paragraph
- cloud.py: add GET /api/cloud/connections/{id}/config endpoint (non-secret fields)
2026-05-30 11:30:13 +02:00
curo1305
4a42ccee5a
feat(05-09): authenticated document preview via fetch + Blob URL
...
- Add fetchDocumentContent() to client.js: fetch with Bearer auth, 401 refresh
retry pattern, returns raw Response (not parsed JSON) for blob() calls
- Replace iframe :src=proxyUrl (unauthenticated) in DocumentPreviewModal.vue
with authenticated fetch → blob → URL.createObjectURL; loading/error states;
URL.revokeObjectURL on unmount to prevent memory leaks
- Replace window.open(rawUrl) in DocumentView.vue openPdf() with
fetchDocumentContent → blob → objectUrl → window.open; 60s auto-revoke
- Frontend build exits 0 with zero errors
- Closes T-05-09-04: no persistent unauthenticated content exposure
2026-05-30 11:18:01 +02:00
curo1305
34b0593782
feat(05-08): add cloud tree components and getCloudFolders API function
...
- Add getCloudFolders(provider, folderId) to api/client.js (GET /api/cloud/folders/{provider}/{folderId})
- Create CloudProviderTreeItem.vue: lazy-load folder tree per connection, providerIconColor computed, expand/collapse arrow, loading/error states
- Create CloudFolderTreeItem.vue: recursive folder tree node with is_dir expand arrow, lazy-load children, depth padding
2026-05-29 08:32:19 +02:00
curo1305
612d542c06
feat(05-07): cloud connections Pinia store + API client functions
...
- Create useCloudConnectionsStore with connections/loading/error refs
- fetchConnections, disconnect(id), disconnectAll() actions
- Append listCloudConnections, disconnectCloud, connectWebDav, updateDefaultStorage to api/client.js
- Add vitest test script to package.json
- 4 unit tests passing (W4 — CLAUDE.md)
2026-05-29 08:05:59 +02:00
curo1305
31f8c00970
fix(phase-4): request() skip res.json() for 204 No Content — fixes delete not updating UI
2026-05-25 22:34:54 +02:00
curo1305
36721575a5
feat(phase-4-09): create new components — FolderRow, FolderBreadcrumb, FolderDeleteModal, ShareModal, DocumentPreviewModal, SearchBar, SortControls, AuditLogTab
...
- FolderRow: inline rename, three-dot menu, delete/rename callbacks, outside-click close
- FolderBreadcrumb: truncation at depth > 4, nav aria-label, ol structure
- FolderDeleteModal: role=dialog, warning icon, doc count in body, Keep/Delete buttons
- ShareModal: handle input, recipients list with revoke, 404/409 error handling
- DocumentPreviewModal: iframe with proxy URL only (never presigned), Escape/overlay close
- SearchBar: role=search, aria-label, Escape clears
- SortControls: aria-pressed, direction indicator, toggle vs switch logic
- AuditLogTab: filters, paginated table, CSV export via window.location.href
- api/client.js: add adminListAuditLog function
2026-05-25 22:10:23 +02:00
curo1305
5417f26b93
feat(phase-4): frontend data layer — API client (13 new functions), folders store, documents store extensions, routes
...
- Extended listDocuments to accept folderId, q, sort, order query params
- Added 6 folder API functions: listFolders, createFolder, getFolder, renameFolder, deleteFolder, moveDocument
- Added 4 share API functions: createShare, listShares, deleteShare, getSharedWithMe
- Added 2 preference API functions: getMyPreferences, updateMyPreferences
- Added getDocumentContentUrl helper (returns URL string, no fetch)
- Created useFoldersStore with full CRUD, navigation state, and breadcrumb support
- Extended useDocumentsStore with currentFolderId, searchQuery, sortField, sortOrder refs
- Added debounced searchQuery watcher (300ms, 2-char minimum, T-04-08-03)
- Added shareDocument, revokeShare, listShares actions to documents store
- Added /folders/:folderId and /shared routes with requiresAuth guard
2026-05-25 21:58:38 +02:00
curo1305 and Claude Sonnet 4.6
b5dde2aad9
wip: Phase 3 UAT in progress — 2/10 tests pass, upload XHR bug open
...
Fixes applied this session:
- frontend/src/api/client.js: noRefreshPaths exclusion prevents auth 401s
from triggering session-expired error on login/register/refresh
- frontend/src/router/index.js: async beforeEach with silent refresh()
restores session from httpOnly cookie on page reload
UAT state: 2 pass (cold-start, admin block), 1 open (XHR upload network error),
7 pending. MinIO PUT fails in browser — needs console output to diagnose.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-24 21:26:50 +02:00
curo1305
eb18428d07
feat(03-05): 3-step presigned upload + quota state in auth store + progress UI
...
- api/client.js: extend request() to attach .status and .payload on 413 structured errors; remove legacy uploadDocument multipart function
- stores/auth.js: add quota ref({used_bytes:0, limit_bytes:0}) and fetchQuota() action (silent catch); expose in store return
- stores/documents.js: replace single upload() with uploadToMinIO XHR helper + 3-step async action (getUploadUrl→XHR PUT→confirmUpload); track uploadProgress map keyed by filename+timestamp (T-03-25); call fetchQuota after upload success and document delete
- components/upload/UploadProgress.vue: add aria progressbar per row, percentage label, quota rejection error block (role=alert, red-50/red-200) from item.quotaError; use plain anchor for Manage storage link
2026-05-23 20:46:24 +02:00
curo1305
349912cac3
feat(03-04): replace settings UI with admin-managed placeholder; update API client
...
- views/SettingsView.vue: Replace full form with static placeholder card. No store
imports, no API calls. Shows "AI configuration is managed by your administrator."
(D-12, T-03-21)
- stores/settings.js: Deleted — only consumed by SettingsView; no other imports
- api/client.js: Remove getSettings, patchSettings, testProvider, getDefaultPrompt
(// Settings section deleted). Add getMyQuota() for quota bar (Plan 03-05).
Add getUploadUrl() and confirmUpload() for presigned upload flow (Plan 03-05).
2026-05-23 20:34:15 +02:00
curo1305
9137f41537
feat(02-05): admin tab components and AdminView
...
- AdminView.vue: tabbed layout (Users | Quotas | AI Config) with UI-SPEC tab strip classes
- AdminUsersTab.vue: user table with create form (crypto.getRandomValues password), inline deactivation confirmation, reactivate, reset-password, row-level spinner, empty state
- AdminQuotasTab.vue: quota inline edit with MB display, usage %, warning when limit < usage
- AdminAiConfigTab.vue: AI provider/model per-user with 1.5s "Saved" confirmation
- client.js: fix adminDeactivateUser/adminReactivateUser to use PATCH /status endpoint, fix adminResetUserPassword to /password-reset, fix adminUpdateAiConfig to send ai_provider/ai_model, add adminGetUserQuota
- No impersonation UI in any admin component (T-02-31)
2026-05-22 20:09:05 +02:00
curo1305 and Claude Sonnet 4.6
3b7d362600
feat(02-02): frontend auth store, router guard, Login/Register views
...
- frontend/src/stores/auth.js: useAuthStore with accessToken in memory
only (never browser storage); login() accepts options.backupCode
- frontend/src/api/client.js: extended with Bearer token injection,
401 auto-refresh retry, all auth/admin API functions, changePassword
- frontend/src/router/index.js: auth routes added (/login, /register,
/password-reset, /account, /admin); beforeEach guard redirects
unauthenticated users to /login with redirect param
- frontend/src/layouts/AuthLayout.vue: centered bare layout for auth pages
- frontend/src/views/auth/LoginView.vue: three-step flow (password, TOTP,
backup code); "Use a backup code instead" link; UI-SPEC copywriting
- frontend/src/views/auth/RegisterView.vue: registration with
PasswordStrengthBar; HIBP error display; UI-SPEC copywriting
- frontend/src/components/auth/PasswordStrengthBar.vue: 4-segment bar
- frontend/src/components/ui/AppSpinner.vue: animate-spin SVG spinner
- Stub views: PasswordResetView, NewPasswordView, AccountView, AdminView
- .gitignore: exclude frontend/node_modules, dist, package-lock.json
npm run build exits 0. All acceptance criteria verified.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-22 19:45:21 +02:00
curo1305 and Claude Sonnet 4.6
7a34807fa0
chore: initial commit — existing single-user document scanner codebase
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-22 08:53:28 +02:00