-
Notifications
You must be signed in to change notification settings - Fork 112
refactor: move from biome to oxlint/oxformat #311
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughSwitches lint/formatter from Biome to oxlint/oxfmt, updates configs and package scripts, applies widespread explicit promise handling (void/await) across client and server, improves error/log message formatting, adjusts path aliases and TypeScript baseUrl, and removes biome.json. Changes
Possibly related PRs
Pre-merge checks❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
1b8cf0e to
e5a0493
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
Fix all issues with AI Agents 🤖
In @app/client/hooks/use-server-events.ts:
- Line 120: The current call to queryClient.invalidateQueries() indiscriminately
invalidates all queries; change it to only invalidate volume-related queries by
using the predicate or specific query key form (e.g.,
queryClient.invalidateQueries({ predicate: q => /* match volume keys */
q.queryKey[0] === 'volumes' || q.queryKey.includes('volume') }) or
queryClient.invalidateQueries(['volumes'])); locate the call to
queryClient.invalidateQueries() in use-server-events.ts (the volume event
handler, analogous to the backup handler) and replace it with a scoped
invalidation that targets your app's volume query keys.
- Line 131: The global call to queryClient.invalidateQueries() blindly
invalidates all queries; narrow it to only volume-related queries by replacing
the unscoped invalidation in use-server-events.ts (the calls at the
invalidateQueries() occurrences around the handlers at lines ~120 and ~131) with
a scoped invalidation that targets your volume query keys (e.g., use
invalidateQueries with a predicate that checks query.queryKey for the 'volumes'
key or the exact volume-related key shape used elsewhere in the app, so only
those queries are invalidated).
- Line 152: Replace the blanket invalidate call (the void
queryClient.invalidateQueries() in use-server-events) with a scoped invalidation
that targets only mirror- or repository-related queries: call
queryClient.invalidateQueries with a predicate (or explicit queryKey array) that
checks query.queryKey for 'mirror' or 'repository' (or matches the specific
mirror/repo id) so only those queries are invalidated instead of all queries.
- Around line 90-91: The current use-server-events handler calls
queryClient.invalidateQueries() and queryClient.refetchQueries() with no filters
which invalidates and refetches the entire cache; change these calls to target
only backup-related queries (e.g., use queryClient.invalidateQueries and
queryClient.refetchQueries with a specific queryKey or a predicate that matches
backup keys such as "backup", "backups", or the backup slice used by your app)
so only backup queries are invalidated/refetched; update the calls in
use-server-events.ts where queryClient.invalidateQueries and
queryClient.refetchQueries are invoked to pass the appropriate queryKey or
predicate for backup queries.
In @app/server/index.ts:
- Around line 25-27: The code calls startup() fire-and-forget and immediately
logs readiness; change this to await the async startup() call and handle errors:
replace the void startup() invocation with an awaited call (await startup()) in
the top-level async context or wrap startup() in a promise chain, then move or
conditionally run logger.info(`Server is running...`) only after startup
resolves successfully; on rejection catch the error, log details with
logger.error including the error object and exit the process (process.exit(1))
to prevent serving before initialization completes.
In @app/server/utils/logger.ts:
- Line 30: Remove the redundant outer String() wrapper around JSON.stringify to
avoid adding extra quotes for string primitives; change the return so it passes
the raw JSON.stringify(m) result into sanitizeSensitiveData (i.e., replace
String(JSON.stringify(m)) with JSON.stringify(m)), ensuring you keep
sanitizeSensitiveData(...) and the variable m unchanged.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
app/server/modules/events/events.controller.ts (1)
16-92: Add error handling for async event handlers to prevent unhandled promise rejections.Event emitters don't automatically handle promises returned from async handlers. When
serverEvents.emit()fires these events, the returned promises are ignored, creating floating promises. Ifstream.writeSSEthrows an error (e.g., client disconnect, write failure), it will result in an unhandled promise rejection.🔎 Recommended fix: Add try-catch blocks to handle errors
-const onBackupStarted = async (data: { scheduleId: number; volumeName: string; repositoryName: string }) => { - await stream.writeSSE({ - data: JSON.stringify(data), - event: "backup:started", - }); -}; +const onBackupStarted = async (data: { scheduleId: number; volumeName: string; repositoryName: string }) => { + try { + await stream.writeSSE({ + data: JSON.stringify(data), + event: "backup:started", + }); + } catch (error) { + logger.error("Failed to write SSE event backup:started:", error); + } +};Apply similar try-catch blocks to all other async event handlers:
onBackupProgress,onBackupCompleted,onVolumeMounted,onVolumeUnmounted,onVolumeUpdated,onMirrorStarted, andonMirrorCompleted.
🧹 Nitpick comments (2)
app/client/modules/backups/components/create-schedule-form.tsx (1)
731-731: Explicit.toString()may be unnecessary.Template literals automatically convert numbers to strings, making the explicit
.toString()call redundant. However, if oxlint requires explicit conversion (which might be the reason for this change during the migration), then it's fine to keep.If not required by oxlint, you could simplify to:
🔎 Optional simplification
-return `${value.toString()} ${label}`; +return `${value} ${label}`;app/server/utils/logger.ts (1)
6-6: Optional: Redundant String() conversion.The
String()wrapper is safe but likely redundant sinceinfo.messageshould already be a string in the winston format context.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (39)
.github/workflows/checks.yml.oxfmtrc.json.oxlintrc.jsonapp/client/components/directory-browser.tsxapp/client/components/layout.tsxapp/client/components/restore-form.tsxapp/client/components/snapshots-table.tsxapp/client/components/volume-file-browser.tsxapp/client/hooks/use-server-events.tsapp/client/modules/auth/routes/download-recovery-key.tsxapp/client/modules/auth/routes/login.tsxapp/client/modules/auth/routes/onboarding.tsxapp/client/modules/backups/components/create-schedule-form.tsxapp/client/modules/backups/components/snapshot-file-browser.tsxapp/client/modules/backups/routes/backup-details.tsxapp/client/modules/backups/routes/create-backup.tsxapp/client/modules/notifications/routes/create-notification.tsxapp/client/modules/notifications/routes/notification-details.tsxapp/client/modules/repositories/routes/create-repository.tsxapp/client/modules/repositories/routes/repository-details.tsxapp/client/modules/settings/routes/settings.tsxapp/client/modules/volumes/routes/create-volume.tsxapp/client/modules/volumes/routes/volume-details.tsxapp/client/modules/volumes/tabs/info.tsxapp/root.tsxapp/server/core/scheduler.tsapp/server/index.tsapp/server/jobs/cleanup-sessions.tsapp/server/modules/backups/__tests__/backups.service.test.tsapp/server/modules/backups/backups.service.tsapp/server/modules/events/events.controller.tsapp/server/utils/logger.tsapp/server/utils/rclone.tsapp/server/utils/restic.tsapp/test/setup.tsbiome.jsoncomponents.jsonpackage.jsontsconfig.json
💤 Files with no reviewable changes (2)
- biome.json
- tsconfig.json
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx,js,jsx,json}
📄 CodeRabbit inference engine (AGENTS.md)
Use Biome for code formatting and linting with
bunx biome check --write ., format only withbunx biome format --write ., or lint withbunx biome lint .
Files:
app/server/modules/backups/backups.service.tsapp/client/modules/settings/routes/settings.tsxapp/client/modules/notifications/routes/notification-details.tsxapp/client/modules/backups/routes/create-backup.tsxapp/client/modules/backups/routes/backup-details.tsxapp/client/modules/auth/routes/login.tsxapp/server/modules/events/events.controller.tsapp/client/modules/backups/components/snapshot-file-browser.tsxapp/client/components/directory-browser.tsxapp/client/components/restore-form.tsxapp/client/modules/auth/routes/onboarding.tsxapp/root.tsxapp/client/components/layout.tsxapp/client/modules/auth/routes/download-recovery-key.tsxapp/client/modules/volumes/tabs/info.tsxapp/client/hooks/use-server-events.tsapp/client/modules/repositories/routes/repository-details.tsxapp/server/jobs/cleanup-sessions.tsapp/server/utils/rclone.tsapp/server/utils/logger.tsapp/client/components/volume-file-browser.tsxapp/server/modules/backups/__tests__/backups.service.test.tsapp/client/components/snapshots-table.tsxapp/client/modules/volumes/routes/create-volume.tsxapp/client/modules/volumes/routes/volume-details.tsxapp/server/index.tsapp/client/modules/repositories/routes/create-repository.tsxapp/client/modules/backups/components/create-schedule-form.tsxapp/server/utils/restic.tspackage.jsoncomponents.jsonapp/server/core/scheduler.tsapp/test/setup.tsapp/client/modules/notifications/routes/create-notification.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Use tabs (not spaces) for indentation with a line width of 120 characters
Use double quotes for strings
Do not auto-organize imports - imports organization is disabled in Biome
All imports must include file extensions when targeting Node/Bun, as the project uses"type": "module"
Files:
app/server/modules/backups/backups.service.tsapp/client/modules/settings/routes/settings.tsxapp/client/modules/notifications/routes/notification-details.tsxapp/client/modules/backups/routes/create-backup.tsxapp/client/modules/backups/routes/backup-details.tsxapp/client/modules/auth/routes/login.tsxapp/server/modules/events/events.controller.tsapp/client/modules/backups/components/snapshot-file-browser.tsxapp/client/components/directory-browser.tsxapp/client/components/restore-form.tsxapp/client/modules/auth/routes/onboarding.tsxapp/root.tsxapp/client/components/layout.tsxapp/client/modules/auth/routes/download-recovery-key.tsxapp/client/modules/volumes/tabs/info.tsxapp/client/hooks/use-server-events.tsapp/client/modules/repositories/routes/repository-details.tsxapp/server/jobs/cleanup-sessions.tsapp/server/utils/rclone.tsapp/server/utils/logger.tsapp/client/components/volume-file-browser.tsxapp/server/modules/backups/__tests__/backups.service.test.tsapp/client/components/snapshots-table.tsxapp/client/modules/volumes/routes/create-volume.tsxapp/client/modules/volumes/routes/volume-details.tsxapp/server/index.tsapp/client/modules/repositories/routes/create-repository.tsxapp/client/modules/backups/components/create-schedule-form.tsxapp/server/utils/restic.tsapp/server/core/scheduler.tsapp/test/setup.tsapp/client/modules/notifications/routes/create-notification.tsx
app/server/modules/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Server follows a modular service-oriented architecture with controller-service-database pattern in each module
Files:
app/server/modules/backups/backups.service.tsapp/server/modules/events/events.controller.tsapp/server/modules/backups/__tests__/backups.service.test.ts
app/client/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
app/client/**/*.{ts,tsx}: Client uses TanStack Query for server state management
Client uses Radix UI primitives with custom Tailwind styling
Use Server-Sent Events hook (use-server-events.ts) for real-time updates in the client
Files:
app/client/modules/settings/routes/settings.tsxapp/client/modules/notifications/routes/notification-details.tsxapp/client/modules/backups/routes/create-backup.tsxapp/client/modules/backups/routes/backup-details.tsxapp/client/modules/auth/routes/login.tsxapp/client/modules/backups/components/snapshot-file-browser.tsxapp/client/components/directory-browser.tsxapp/client/components/restore-form.tsxapp/client/modules/auth/routes/onboarding.tsxapp/client/components/layout.tsxapp/client/modules/auth/routes/download-recovery-key.tsxapp/client/modules/volumes/tabs/info.tsxapp/client/hooks/use-server-events.tsapp/client/modules/repositories/routes/repository-details.tsxapp/client/components/volume-file-browser.tsxapp/client/components/snapshots-table.tsxapp/client/modules/volumes/routes/create-volume.tsxapp/client/modules/volumes/routes/volume-details.tsxapp/client/modules/repositories/routes/create-repository.tsxapp/client/modules/backups/components/create-schedule-form.tsxapp/client/modules/notifications/routes/create-notification.tsx
app/client/modules/*/routes/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Routes should be organized in feature modules at
app/client/modules/*/routes/
Files:
app/client/modules/settings/routes/settings.tsxapp/client/modules/notifications/routes/notification-details.tsxapp/client/modules/backups/routes/create-backup.tsxapp/client/modules/backups/routes/backup-details.tsxapp/client/modules/auth/routes/login.tsxapp/client/modules/auth/routes/onboarding.tsxapp/client/modules/auth/routes/download-recovery-key.tsxapp/client/modules/repositories/routes/repository-details.tsxapp/client/modules/volumes/routes/create-volume.tsxapp/client/modules/volumes/routes/volume-details.tsxapp/client/modules/repositories/routes/create-repository.tsxapp/client/modules/notifications/routes/create-notification.tsx
app/root.tsx
📄 CodeRabbit inference engine (AGENTS.md)
Client entry point is
app/root.tsxwith React Router v7 SSR
Files:
app/root.tsx
app/server/jobs/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
New scheduled jobs must extend
Jobclass, implementrun()method, and be registered inapp/server/modules/lifecycle/startup.tswith a cron expression
Files:
app/server/jobs/cleanup-sessions.ts
app/server/index.ts
📄 CodeRabbit inference engine (AGENTS.md)
Server entry point is
app/server/index.tsand initializes the main API server on port 4096
Files:
app/server/index.ts
app/server/utils/restic.ts
📄 CodeRabbit inference engine (AGENTS.md)
app/server/utils/restic.ts: Restic password file must have 0600 permissions and should never be exposed
UpdatebuildRepoUrl()inapp/server/utils/restic.tswhen adding a new repository backend
UpdatebuildEnv()inapp/server/utils/restic.tsto handle credentials and configuration when adding a new repository backend
Restic password file is stored in/var/lib/zerobyte/restic/passwordand auto-generated on first run
Restic cache is stored in/var/lib/zerobyte/restic/cache
Files:
app/server/utils/restic.ts
🧠 Learnings (23)
📓 Common learnings
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json} : Use Biome for code formatting and linting with `bunx biome check --write .`, format only with `bunx biome format --write .`, or lint with `bunx biome lint .`
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to app/root.tsx : Client entry point is `app/root.tsx` with React Router v7 SSR
Applied to files:
app/client/modules/auth/routes/login.tsx
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to app/client/modules/*/routes/**/*.{ts,tsx} : Routes should be organized in feature modules at `app/client/modules/*/routes/`
Applied to files:
app/client/modules/auth/routes/login.tsx
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to app/client/**/*.{ts,tsx} : Use Server-Sent Events hook (`use-server-events.ts`) for real-time updates in the client
Applied to files:
app/server/modules/events/events.controller.tsapp/client/hooks/use-server-events.ts
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to app/server/modules/backends/backend.ts : Update backend factory in `app/server/modules/backends/backend.ts` when adding a new volume backend
Applied to files:
app/server/modules/events/events.controller.tsapp/client/modules/volumes/tabs/info.tsxapp/client/modules/volumes/routes/create-volume.tsxapp/client/modules/volumes/routes/volume-details.tsx
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to app/client/**/*.{ts,tsx} : Client uses TanStack Query for server state management
Applied to files:
app/root.tsxapp/client/hooks/use-server-events.tsapp/client/components/snapshots-table.tsx
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to app/schemas/volumes.ts : Add schemas for new volume backends to `app/schemas/volumes.ts` and update `volumeConfigSchema` discriminated union
Applied to files:
app/client/modules/volumes/tabs/info.tsxapp/client/modules/volumes/routes/create-volume.tsxapp/client/modules/volumes/routes/volume-details.tsx
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use tabs (not spaces) for indentation with a line width of 120 characters
Applied to files:
.oxfmtrc.json
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to app/server/utils/restic.ts : Update `buildRepoUrl()` in `app/server/utils/restic.ts` when adding a new repository backend
Applied to files:
app/client/modules/repositories/routes/repository-details.tsxapp/server/utils/restic.ts
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to app/server/modules/repositories/repositories.dto.ts : Add DTO schemas in `app/server/modules/repositories/repositories.dto.ts` when adding a new repository backend
Applied to files:
app/client/modules/repositories/routes/repository-details.tsxapp/client/modules/repositories/routes/create-repository.tsx
📚 Learning: 2025-12-22T19:49:56.761Z
Learnt from: nicotsx
Repo: nicotsx/zerobyte PR: 197
File: app/client/modules/repositories/components/create-repository-form.tsx:112-112
Timestamp: 2025-12-22T19:49:56.761Z
Learning: During the repository import flow, when users provide a full path to an existing restic repository, do not implement server-side path sanitization for this flow. Rely on Restic to validate the path; the operation will fail if the path does not point to a valid restic repository. This guidance applies to repository import components under app/client/modules/repositories (not just the specified file).
Applied to files:
app/client/modules/repositories/routes/repository-details.tsxapp/client/modules/repositories/routes/create-repository.tsx
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to app/server/jobs/**/*.ts : New scheduled jobs must extend `Job` class, implement `run()` method, and be registered in `app/server/modules/lifecycle/startup.ts` with a cron expression
Applied to files:
app/server/jobs/cleanup-sessions.tsapp/server/core/scheduler.ts
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to app/server/core/capabilities.ts : System will gracefully degrade if rclone capability is unavailable, requiring `/root/.config/rclone` directory access
Applied to files:
app/server/utils/rclone.ts
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to app/server/index.ts : Server entry point is `app/server/index.ts` and initializes the main API server on port 4096
Applied to files:
app/server/index.ts
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to app/server/modules/**/*.ts : Server follows a modular service-oriented architecture with controller-service-database pattern in each module
Applied to files:
app/server/index.ts
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to app/server/utils/restic.ts : Update `buildEnv()` in `app/server/utils/restic.ts` to handle credentials and configuration when adding a new repository backend
Applied to files:
app/server/utils/restic.ts
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to app/server/utils/restic.ts : Restic cache is stored in `/var/lib/zerobyte/restic/cache`
Applied to files:
app/server/utils/restic.ts
📚 Learning: 2025-11-29T15:55:09.080Z
Learnt from: nicotsx
Repo: nicotsx/zerobyte PR: 78
File: app/server/modules/repositories/repositories.service.ts:221-223
Timestamp: 2025-11-29T15:55:09.080Z
Learning: Restic's restore command has built-in path validation that prevents writing outside the specified --target directory. It normalizes and validates paths to reject any attempts to escape the target location, so application-level path sanitization is not required when using restic restore.
Applied to files:
app/server/utils/restic.ts
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json} : Use Biome for code formatting and linting with `bunx biome check --write .`, format only with `bunx biome format --write .`, or lint with `bunx biome lint .`
Applied to files:
package.json
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Use `bun run tsc` for type checking and generating React Router types
Applied to files:
package.json
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Use `bun run test` to run all tests, or `bunx dotenv-cli -e .env.test -- bun test --preload ./app/test/setup.ts` for specific test files
Applied to files:
package.json
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Use `bun run build` for production builds
Applied to files:
package.json
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Use `bun run gen:api-client` to generate TypeScript API client from OpenAPI spec
Applied to files:
package.json
🧬 Code graph analysis (7)
app/server/modules/backups/backups.service.ts (3)
app/server/utils/logger.ts (1)
logger(36-41)app/server/utils/errors.ts (1)
toMessage(16-19)app/server/index.ts (1)
error(48-50)
app/client/modules/repositories/routes/repository-details.tsx (1)
app/client/api-client/@tanstack/react-query.gen.ts (2)
listSnapshotsOptions(464-475)deleteRepositoryMutation(393-405)
app/server/jobs/cleanup-sessions.ts (1)
app/server/modules/auth/auth.service.ts (1)
authService(179-179)
app/server/utils/logger.ts (1)
app/server/utils/sanitize.ts (1)
sanitizeSensitiveData(5-22)
app/server/modules/backups/__tests__/backups.service.test.ts (1)
app/server/modules/backups/backups.service.ts (1)
backupsService(723-738)
app/server/index.ts (1)
app/server/modules/lifecycle/startup.ts (1)
startup(44-87)
app/server/utils/restic.ts (1)
app/server/utils/logger.ts (1)
logger(36-41)
🔇 Additional comments (42)
app/client/modules/volumes/tabs/info.tsx (1)
40-40: LGTM—Explicit fire-and-forget navigation.The
voidoperator correctly discards the Promise returned bynavigate(), making the fire-and-forget intent explicit. This is appropriate here since the mutation has already succeeded, the toast is shown, and no follow-up logic depends on navigation completing.
Note: The retrieved learning mentions using Biome for linting, but this PR specifically migrates the project from Biome to oxlint/oxformat, so that guideline is now outdated.
app/client/modules/backups/routes/create-backup.tsx (1)
62-62: LGTM! Proper handling of fire-and-forget promise.The
voidoperator correctly indicates intentional fire-and-forget behavior for the navigation promise, satisfying oxlint's floating promise rules.
Note: The coding guidelines and retrieved learnings still reference Biome for linting and formatting. These should be updated to reflect the migration to oxlint/oxformat as part of this PR or in a follow-up.
Based on learnings and coding guidelines that reference Biome, which this PR is moving away from.
app/server/modules/events/events.controller.ts (1)
1-126: Update coding guidelines to reflect the tooling change from Biome to oxlint/oxformat.The coding guidelines and retrieved learnings still reference Biome for formatting and linting, but this PR removes Biome in favor of oxlint/oxformat. Please update the project documentation (likely
AGENTS.mdor similar) to reflect the new tooling commands and usage.Based on learnings, the project previously used Biome, but this PR transitions to oxlint/oxformat—please ensure all documentation is updated accordingly.
app/server/utils/restic.ts (3)
361-362: LGTM: Explicit cleanup logic is clearer.The refactoring from logical AND expressions to explicit if statements improves readability without changing behavior. Both nullable file paths are properly handled.
396-396: LGTM: Improved error logging with arktype's summary.The changes correctly use the
summaryproperty from arktype'stype.errorsinstances to produce concise, human-readable validation error messages. This is the recommended approach for logging arktype validation failures and provides better diagnostics than logging the entire error object.Also applies to: 487-487, 532-533, 715-716, 725-725
1-930: Note: Biome-related learnings and guidelines are now outdated.This PR migrates the project from Biome to oxlint/oxformat. The retrieved learnings and coding guidelines that reference Biome should be updated to reflect the new tooling.
Based on learnings and coding guidelines, the project previously used Biome for formatting and linting, but this PR replaces it with oxlint/oxformat.
app/server/core/scheduler.ts (2)
43-49: Verify iftask.destroy()is asynchronous.According to the standard node-cron API,
destroy()is a synchronous method that returnsvoid, not aPromise. Awaiting a synchronous method is unnecessary and misleading.If
destroy()is indeed synchronous, remove theawait. If it is asynchronous in your node-cron version, consider usingPromise.all()for concurrent execution instead of sequential awaiting.🔎 Proposed fix if destroy() is synchronous
async clear() { for (const task of this.tasks) { - await task.destroy(); + task.destroy(); } this.tasks = []; logger.info("Scheduler cleared all tasks"); }
35-41: No changes needed. Theawaitkeywords fortask.stop()andtask.destroy()are correct.Node-cron's
stop()anddestroy()methods have signatures that returnvoid | Promise<void>depending on the task type (synchronous for basic in-process tasks, asynchronous for background/forked tasks). Awaiting these methods properly handles both cases and ensures cleanup completion before proceeding, which is the correct pattern.Likely an incorrect or invalid review comment.
app/client/modules/auth/routes/login.tsx (1)
50-56: LGTM! Fire-and-forget navigation pattern is appropriate.The
voidoperator correctly signals that the navigation promises are intentionally not awaited. This is the right approach for post-login navigation where you want to redirect immediately without blocking on the navigation promise.app/client/modules/backups/components/snapshot-file-browser.tsx (1)
70-77: LGTM! Prefetch fire-and-forget pattern is correct.Using
voidwithprefetchQueryis the appropriate pattern for optimistic data prefetching. The prefetch is an optimization that doesn't require waiting for completion.app/client/modules/repositories/routes/create-repository.tsx (1)
35-41: LGTM! Fire-and-forget navigation after successful creation.The
voidoperator appropriately signals that the navigation promise is intentionally discarded. This is the correct pattern for post-mutation navigation.app/root.tsx (1)
27-37: LGTM! Fire-and-forget query invalidation is appropriate for mutation cache handlers.Using
voidwithinvalidateQueries()correctly signals that these invalidations are intentionally not awaited. This is a common pattern in mutation cache configuration where you want to trigger cache updates without blocking the mutation lifecycle.Note: If invalidation fails silently, stale data might persist in the cache. This is the existing behavior, now made explicit through the
voidoperator.app/server/modules/backups/backups.service.ts (1)
22-36: LGTM! Error message formatting is now consistent.Using
toMessage(error)for logging aligns with the error handling pattern used throughout this file and ensures proper sanitization of sensitive data. This change makes the error logging consistent with other catch blocks in this service (e.g., lines 255, 323, 328, 371, 375, 403).app/client/modules/notifications/routes/notification-details.tsx (1)
69-69: LGTM: Fire-and-forget navigation is appropriate here.The
voidoperator correctly marks the navigation promise as intentionally ignored after successful deletion.app/client/modules/repositories/routes/repository-details.tsx (2)
70-70: LGTM: Prefetch optimization correctly marked as fire-and-forget.The
voidoperator appropriately indicates that the prefetch promise result is intentionally ignored.
77-77: LGTM: Fire-and-forget navigation is appropriate here.The
voidoperator correctly marks the navigation promise as intentionally ignored after successful deletion.app/client/modules/notifications/routes/create-notification.tsx (1)
36-36: LGTM: Fire-and-forget navigation is appropriate here.The
voidoperator correctly marks the navigation promise as intentionally ignored after successful creation..oxfmtrc.json (1)
1-6: RemoveexperimentalSortImportsas it enables automatic import organization.The
experimentalSortImports: {}setting actively enables oxfmt's import sorting feature with default settings. This conflicts with the project coding guidelines that specify: "Do not auto-organize imports - imports organization is disabled in Biome." Remove this line from the configuration to comply with project standards.⛔ Skipped due to learnings
Learnt from: CR Repo: nicotsx/zerobyte PR: 0 File: AGENTS.md:0-0 Timestamp: 2025-12-28T17:31:39.171Z Learning: Applies to **/*.{ts,tsx,js,jsx} : Do not auto-organize imports - imports organization is disabled in BiomeLearnt from: CR Repo: nicotsx/zerobyte PR: 0 File: AGENTS.md:0-0 Timestamp: 2025-12-28T17:31:39.171Z Learning: Applies to **/*.{ts,tsx,js,jsx,json} : Use Biome for code formatting and linting with `bunx biome check --write .`, format only with `bunx biome format --write .`, or lint with `bunx biome lint .`Learnt from: CR Repo: nicotsx/zerobyte PR: 0 File: AGENTS.md:0-0 Timestamp: 2025-12-28T17:31:39.171Z Learning: Applies to **/*.{ts,tsx,js,jsx} : Use tabs (not spaces) for indentation with a line width of 120 charactersapp/client/modules/auth/routes/download-recovery-key.tsx (1)
45-45: LGTM! Proper fire-and-forget pattern.The
voidoperator correctly indicates that the navigation promise is intentionally discarded. This is the standard pattern to satisfy linters while preserving the fire-and-forget behavior.app/client/modules/backups/routes/backup-details.tsx (1)
123-123: LGTM! Correct promise handling pattern.The
voidoperator appropriately indicates intentional fire-and-forget navigation after successful schedule deletion.app/client/modules/volumes/routes/create-volume.tsx (1)
36-36: LGTM! Proper fire-and-forget navigation.The
voidoperator correctly handles the intentionally discarded navigation promise after successful volume creation.app/client/components/volume-file-browser.tsx (1)
49-54: LGTM! Correct fire-and-forget prefetch pattern.The
voidoperator appropriately indicates that the prefetch operation is intentionally fire-and-forget. Prefetching doesn't require waiting for completion, making this pattern ideal..github/workflows/checks.yml (1)
28-31: Configuration file is properly in place for oxlint-action migration.The
.oxlintrc.jsonconfiguration file exists and is valid JSON. The migration to oxlint-action withdeny-warnings: trueis properly configured for strict linting enforcement.app/server/jobs/cleanup-sessions.ts (1)
5-9: LGTM! Proper async handling.Adding
awaitensures the session cleanup completes before returning the result, which is the correct pattern for this scheduled job.app/client/modules/auth/routes/onboarding.tsx (1)
57-60: LGTM! Correct fire-and-forget pattern.The
voidoperator explicitly indicates the navigation promise is intentionally discarded, satisfying thetypescript/no-floating-promiseslint rule while maintaining the intended behavior.app/server/utils/rclone.ts (1)
3-3: LGTM! Improved error message formatting.The changes consistently improve error handling:
- Explicit
.toString()conversions make type handling cleartoMessage()utility standardizes error formatting across the codebaseThese align with the error handling patterns observed in other server modules.
Also applies to: 13-13, 40-40, 74-74
.oxlintrc.json (1)
1-150: LGTM! Comprehensive oxlint configuration.The configuration provides a thorough set of linting rules appropriate for migrating from Biome to oxlint:
- The
typescript/no-floating-promisesrule (line 84) drives thevoidoperator usage seen throughout the PR- Severity set to "warn" eases migration while still surfacing issues
- Appropriate ignore patterns for generated code (
api-client)Note: This PR intentionally supersedes the retrieved learning about using Biome for linting, as the migration to oxlint is the explicit purpose of this refactor.
Based on learnings, the previous guideline recommended Biome, but this PR deliberately replaces it with oxlint/oxformat.
components.json (1)
14-18: LGTM! Path aliases are now more explicit.The updated aliases clearly indicate client-side code paths, improving code organization and maintainability.
package.json (2)
7-7: Update coding guidelines and learnings to reflect the Biome → oxlint migration.The lint script change looks good and aligns with the PR objectives. However, the coding guidelines and learnings still reference Biome for formatting and linting, which conflicts with this change.
Based on coding guidelines and learnings, the documentation needs updating to replace references to Biome with oxlint/oxfmt commands.
103-105: All oxlint package versions verified and secure.The specified versions (oxfmt@0.22.0, oxlint@1.36.0, oxlint-tsgolint@0.10.1) all exist on npm, carry no known security advisories, and are actively maintained as part of the oxc project.
app/client/modules/settings/routes/settings.tsx (1)
57-57: LGTM! Fire-and-forget navigation is appropriate here.The
voidoperator correctly handles the navigation Promise in the logout flow. Since we're redirecting to login, we don't need to await the result.app/client/components/directory-browser.tsx (1)
26-26: LGTM! Fire-and-forget prefetch is appropriate.Prefetching is naturally a fire-and-forget operation, and the
voidoperator properly handles the Promise to satisfy linting requirements.app/client/modules/volumes/routes/volume-details.tsx (1)
76-79: LGTM! Fire-and-forget navigation pattern.The
voidoperator explicitly discards the Promise returned bynavigate, satisfying the new linter's requirement to handle all promises. This is a standard fire-and-forget pattern for post-mutation navigation.app/client/components/layout.tsx (1)
32-34: LGTM! Fire-and-forget navigation pattern.The
voidoperator explicitly discards the Promise returned bynavigate, satisfying the new linter's requirement. The logout flow correctly navigates to the login page without awaiting the navigation Promise.app/test/setup.ts (1)
7-14: LGTM! Logger mock configuration is correct.The
voidoperator is applied to themock.module()call for consistency with the linter configuration. Whilemock.module()is synchronous in Bun, this change is harmless and maintains consistency with the PR's broader pattern of explicitly handling all return values.app/client/components/restore-form.tsx (2)
85-92: LGTM! Fire-and-forget prefetch pattern.The
voidoperator appropriately handles the Promise returned byprefetchQuery. This prefetch operation is intended to run in the background without blocking the user interaction.
101-106: LGTM! Fire-and-forget navigation pattern.The
voidoperator explicitly discards the Promise returned bynavigate, satisfying the linter requirement. Navigation after successful restore is appropriate and doesn't need to be awaited.app/server/modules/backups/__tests__/backups.service.test.ts (1)
104-104: LGTM! Fire-and-forget pattern for concurrency test.The
voidoperator is appropriate here to start the first backup without awaiting it, allowing the test to verify that a second concurrent call is correctly skipped. The test logic correctly validates the concurrency guard inexecuteBackup.app/client/components/snapshots-table.tsx (4)
52-56: LGTM! Proper promise handling with void operator.The addition of the
voidoperator correctly indicates that the promise returned byinvalidateQueries()is intentionally ignored. This is safe here since the subsequent state updates don't depend on the invalidation completing, and the query refetch will happen automatically.
64-67: LGTM! Consistent promise handling.The
voidoperator is correctly applied here, consistent with the pattern used in thedeleteSnapshotsmutation above.
72-74: LGTM! Standard fire-and-forget navigation pattern.The
voidoperator appropriately marks the navigation as a fire-and-forget operation, which is the standard pattern for click handlers.
1-307: Note: Coding guidelines reference outdated tooling.The coding guidelines and learnings still reference Biome for linting and formatting, but this PR transitions the project to oxlint and oxformat. Consider updating the guidelines and learnings to reflect the new tooling.
Based on coding guidelines and learnings, which reference outdated tooling being replaced by this PR.
This reverts commit 525dcd8.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
app/server/index.ts (1)
25-25: Excellent fix - critical race condition resolved.The change from
void startup();toawait startup();correctly addresses the previous critical issue. The server will now complete all initialization (scheduler setup, volume mounting, job scheduling) before proceeding to create the HTTP server on line 41.Optional: Consider adding error handling and success logging.
For improved robustness and observability, you might add:
🔎 Optional improvements
+try { await startup(); + logger.info("Server startup completed successfully"); +} catch (err) { + logger.error(`Server startup failed: ${err instanceof Error ? err.message : String(err)}`); + process.exit(1); +}
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
.oxfmtrc.jsonapp/server/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- .oxfmtrc.json
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx,json}
📄 CodeRabbit inference engine (AGENTS.md)
Use Biome for code formatting and linting with
bunx biome check --write ., format only withbunx biome format --write ., or lint withbunx biome lint .
Files:
app/server/index.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Use tabs (not spaces) for indentation with a line width of 120 characters
Use double quotes for strings
Do not auto-organize imports - imports organization is disabled in Biome
All imports must include file extensions when targeting Node/Bun, as the project uses"type": "module"
Files:
app/server/index.ts
app/server/index.ts
📄 CodeRabbit inference engine (AGENTS.md)
Server entry point is
app/server/index.tsand initializes the main API server on port 4096
Files:
app/server/index.ts
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json} : Use Biome for code formatting and linting with `bunx biome check --write .`, format only with `bunx biome format --write .`, or lint with `bunx biome lint .`
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Do not auto-organize imports - imports organization is disabled in Biome
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to app/server/index.ts : Server entry point is `app/server/index.ts` and initializes the main API server on port 4096
Applied to files:
app/server/index.ts
📚 Learning: 2025-12-28T17:31:39.171Z
Learnt from: CR
Repo: nicotsx/zerobyte PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-28T17:31:39.171Z
Learning: Applies to app/server/modules/**/*.ts : Server follows a modular service-oriented architecture with controller-service-database pattern in each module
Applied to files:
app/server/index.ts
🧬 Code graph analysis (1)
app/server/index.ts (1)
app/server/modules/lifecycle/startup.ts (1)
startup(44-87)
* chore: install and configure oxlint * chore: fix liniting issues * chore: install and configure oxfmt * ci: add oxlint action instead of biome * chore: pr feedbacks * Revert "chore: pr feedbacks" This reverts commit 525dcd8.
Allows for more eslint compatible rules & type aware linting
Summary by CodeRabbit
Bug Fixes
Chores
✏️ Tip: You can customize this high-level summary in your review settings.