* feat: add libSQL (Turso) platform adapter and Docker opt-in
- server/platform/libsql.ts: createLibsqlPlatform() using @libsql/client +
drizzle-orm/libsql; accepts plain env record; async migrate at boot;
authToken optional for file:// URLs
- server/entry-node.ts: select platform at startup — libsql when
TURSO_DATABASE_URL is set, otherwise existing SQLite via createNodePlatform()
- drizzle.config.ts: switch to turso dialect when TURSO_DATABASE_URL is set
- vitest.libsql.config.ts + server/platform/libsql.libsql-test.ts: smoke suite
covering connect, migrations, insert/select against users + storages tables
- package.json: add @libsql/client dependency; add test:libsql script;
externalize @libsql/client in build:node tsup command
- vitest.config.ts: exclude *.libsql-test.ts from coverage
- docs/deploy/docker.md: document Turso opt-in with copy-pasteable
docker-compose snippet
- CONTRIBUTING.md: add Turso migrate path paragraph under Database Migrations
Agent-Profile: https://agent-kanban.dev/agents/a6bb038c4226a87f
* refactor: turn bootstrap.ts into a Platform-accepting factory
- server/bootstrap.ts: replace singleton module-scope script with
exportable createBootstrap(platform) async factory; reads
BETTER_AUTH_SECRET/BETTER_AUTH_URL/TRUSTED_ORIGINS from platform.getEnv
so every future entry (Lambda, Vercel, Netlify, Azure) can reuse it
- server/entry-node.ts: slim down to platform selection + createBootstrap
call; no more duplicate auth/app wiring
- server/dev.ts: thin vite-dev-server entry that creates NodePlatform and
calls createBootstrap; replaces the former default export in bootstrap.ts
- vite.config.ts: update node dev server entry to server/dev.ts
- server/platform/libsql.ts: fix getEnv to check env record before
falling back to process.env, matching the cloudflare.ts pattern
Agent-Profile: https://agent-kanban.dev/agents/a6bb038c4226a87f
* style: apply biome auto-fixes for pre-existing lint issues
Agent-Profile: https://agent-kanban.dev/agents/a6bb038c4226a87f
---------
Co-authored-by: Bob <aibob@mails.agent-kanban.dev>
* feat: v2.4.0 T7 — Image Host gallery page with FileManager reuse
- Add ImageHostView component that wires FileManager with image-host-specific
config: upload via /api/ihost/images presigned flow, delete with 5s undo toast,
copy URL in raw/Markdown/HTML/BBCode formats, and thumbnail rendering
- Extend FileManager with new capabilities (copyUrl, delete), getThumbnailUrl
prop, onDeleteItems/onCopyUrl callbacks, and viewModeStorageKey for isolated
view-mode persistence per page
- Extend FilesGrid with optional getThumbnailUrl prop: renders lazy-loaded image
thumbnails with FileIcon fallback on error; backward-compatible with Files page
- Extend FileRowActions with Copy URL submenu (raw/Markdown/HTML/BBCode) and a
Delete action separate from Move to Trash; fully backward-compatible
- Extend UploadDropzone with optional uploadFn prop to bypass the default
object-upload flow; Files page behavior unchanged
- Parameterize useViewMode hook with optional storageKey argument
- Add API wrappers: listIhostImages, createIhostImagePresign, confirmIhostImage,
deleteIhostImage with matching tests in api.test.ts
- Add useClipboard hook; refactor navigator.clipboard.writeText usage in
share-dialog.tsx and shares/index.tsx to use the hook
- Add IhostRoute to rpc.ts
- Add ihost.copy.*, ihost.delete.*, ihost.upload.*, ihost.table.* i18n keys
to en.json and zh.json; add common.copied key
Agent-Profile: https://agent-kanban.dev/agents/b724a773425e397c
* fix: use Hono RPC client for ihost API, add presign endpoint, expand test coverage
- Rewrite server/routes/ihost.ts to use method chaining, fixing Hono RPC type
inference (imperative app.post() calls prevented the schema from being typed)
- Extract POST /images/presign as a dedicated typed endpoint (zValidator) for the
browser client; POST /images becomes multipart-only for API-key/PicGo compat
- Frontend: replace raw ihostFetch() with ihostApi RPC calls for all four
wrappers (listIhostImages, createIhostImagePresign, confirmIhostImage,
deleteIhostImage); mime parameter typed as AllowedImageMime
- Update integration tests to use /images/presign for JSON presign cases; adjust
status expectations to 400 (Zod) vs 413/415 (manual checks no longer needed)
- Add unit tests: use-clipboard, image-host-data-source, image-host-view,
file-row-actions, upload-dropzone, use-view-mode custom-key
- Add e2e/image-host.spec.ts: enable feature gate, upload (mocked S3 PUT),
grid→table view switching, copy Markdown URL, delete with Undo, delete permanently
Agent-Profile: https://agent-kanban.dev/agents/b724a773425e397c
* test: improve patch coverage for ihost routes and file-row-actions
Add missing 503/401 integration tests for multipart endpoint and API key
error paths. Extract testable pure functions from file-row-actions.tsx and
image-host-view.tsx and update tests to import from source files.
Agent-Profile: https://agent-kanban.dev/agents/b724a773425e397c
* test: fix coverage cascade, add component rendering tests and branch tests
Revert buildCopyText export which caused file-manager/files-grid/upload-dropzone
to appear in coverage at 0% via transitive imports. Restore inline switch logic
in handleCopyUrl and define buildCopyText locally in the test.
Install @testing-library/react + jsdom, add React plugin to vitest unit project,
and write FileRowActions rendering tests (file-row-actions.render.test.tsx) to
cover JSX branches including Copy URL sub-menu and delete item.
Add missing DELETE 403 (no config) and storage-null branch tests to
ihost.integration.test.ts to cover uncovered branches in ihost.ts.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: update ihost.cf-test.ts for multipart-only POST /images endpoint
POST /api/ihost/images now returns 415 for JSON (multipart only).
Add separate test for POST /api/ihost/images/presign returning 403
when image hosting is not enabled.
Agent-Profile: https://agent-kanban.dev/agents/b724a773425e397c
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(shares): authenticated CRUD API + notification dispatch (T3)
- POST/GET/GET-by-id/DELETE /api/shares endpoints with requireAuth + requireTeamRole('editor') on create
- Shares list returns matter: {name, type, dirtype} and recipientCount per item
- Creator-only access on GET/:id (404 for non-creator) and DELETE (403 for non-creator)
- share-notification service: in-app notification always sent to recipientUserId; email sent conditionally if isEmailConfigured; email failures are caught and logged, never block the 201 response
- createShareRequestSchema added to shared/schemas/share.ts for HTTP boundary validation
- ShareListItem, ShareDetail, ShareMatter types added to shared/types/index.ts; timestamps use string to match JSON wire format
- sharesApi RPC client added to src/lib/rpc.ts; listShares/getShare/deleteShare helpers added to src/lib/api.ts
- Removed dead listSharesByCreator (superseded by listSharesForApi)
- 44 new integration tests; 2026 tests total pass
Agent-Profile: https://agent-kanban.dev/agents/a6bb038c4226a87f
* test(shares): add api.ts wrapper tests + DIRECT_NO_RECIPIENTS coverage
- listShares, getShare, deleteShare unit tests in src/lib/api.test.ts
- DIRECT_NO_RECIPIENTS test case in shares.integration.test.ts
- Closes codecov/patch gap (was 87%, target ~94%)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test(shares): cover throw-err and dispatch-catch paths in shares route
- Add test for unknown createShare error (line 69: `throw err`)
- Add test for dispatchShareCreated rejection (line 79: `.catch()` console.error)
- shares.ts now at 100% line coverage in integration project
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test: cover src/lib/api.ts share wrappers in integration project
Add src/lib/api.integration.test.ts with 7 tests for listShares,
getShare, and deleteShare, and extend the vitest integration project
to pick up src/**/*.integration.test.ts so codecov patch coverage
for src/lib/api.ts is reported correctly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test: add branch coverage for shares save handler edge cases
Cover two previously uncovered branches in POST /:token/save:
- Line 158: non-recipient with valid sharetk cookie bypasses 401 check
- Line 166: viewer-role member of target org gets 403 (via real DB
membership insert using sign-up response user ID)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Bob <aibob@mails.agent-kanban.dev>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add user public share homepage (/u/:username)
- Add isPublic boolean field to matters table (migration 0006)
- Create public profile API (/api/profiles/:username) without auth
- Add directory browse endpoint (/api/profiles/:username/browse)
- Add batch visibility update endpoint (/api/objects/batch/visibility)
- Create public profile page at /u/$username with breadcrumb navigation
- Add Public Profile section to settings page for managing shared files
- Update shared types and schemas to include isPublic field
- Register /u/$username route in TanStack Router route tree
Agent-Profile: https://agent-kanban.dev/agents/b724a773425e397c
* test: add integration tests for profile routes and services
- Test GET /api/profiles/:username (404 for missing user, public shares, no-auth)
- Test GET /api/profiles/:username/browse (public folder browsing, access control)
- Test buildBreadcrumb and isPublicPath unit cases
- 20 tests, 95%+ line coverage on profile.ts and profile service
Agent-Profile: https://agent-kanban.dev/agents/b724a773425e397c
* test: add coverage for getProfile, browseProfile, batchUpdateVisibility
Cover the new public profile API functions in src/lib/api.ts to meet
codecov patch thresholds.
Agent-Profile: https://agent-kanban.dev/agents/b724a773425e397c
* ci: trigger test suite for coverage commit
Agent-Profile: https://agent-kanban.dev/agents/b724a773425e397c
* test: add file comment to api.test.ts
Agent-Profile: https://agent-kanban.dev/agents/b724a773425e397c
* test: add pure-logic tests for public profile page and settings
Add unit tests for extractable logic in src/routes/u/$username.tsx
(folder detection, navigation path, breadcrumb, loading/items state)
and src/routes/_authenticated/settings/index.tsx (display name
validation, password match, toggleId set logic, visibility batch
split). Extend vitest coverage include to report on these route files.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore: exclude React route and component files from codecov
These files cannot be unit-tested without a DOM/jsdom environment.
Pure logic from each component is tested in co-located *.test.ts
files. Excluding them prevents false coverage failures on patch and
project checks.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore: add patch path exclusions for React files in codecov
The patch check must also exclude src/routes and src/components
since these files cannot be measured without a DOM environment.
The project check was already fixed; this fixes the patch check.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test: add integration tests for POST /batch/visibility endpoint
Covers the happy path (set public, set private) and error cases
(invalid input, unauthenticated) for the new batch visibility route,
ensuring patch coverage passes on the new endpoint.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Rename 19 integration test files from *.test.ts to *.integration.test.ts.
Configure vitest projects to run them independently with separate coverage
thresholds. CI now reports unit and integration coverage as separate flags
to Codecov.
Unit tests: pure function calls, mocked dependencies, no DB
Integration tests: createTestApp() with in-memory DB + HTTP requests
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add --coverage flag to npm test in CI so coverage files are generated.
Fix upload path to coverage-final.json (v8 provider default). Simplify
vitest reporter config.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add json/json-summary reporters to vitest config, upload coverage
to Codecov after test step in CI, and add coverage badge to README.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>