Skip to content
This repository was archived by the owner on Jan 13, 2026. It is now read-only.

ITO-448: Create Interactions Directly from transcribe stream#455

Merged
fulltimemike merged 5 commits intodevfrom
ito-448
Dec 1, 2025
Merged

ITO-448: Create Interactions Directly from transcribe stream#455
fulltimemike merged 5 commits intodevfrom
ito-448

Conversation

@fulltimemike
Copy link
Collaborator

This one has a few extras thrown in, but the gist of changes is:

  • Create interactions directly from the transcribeStreamHandlerV2. TranscribeStreamHandler v1 should be deleted at some point, as it is getting a minor fraction of traffic
  • Delete pushing interactions from the client application (older versions will attempt to push, but throw errors as part of the sync cycle if they attempt to overwrite interactions already in the database. Because interactions can only be created after the transcribe stream endpoint returns, we are almost guaranteed that the interaction will be created serverside before the client can overwrite it. There could be a malicious case where a client attempts to create an interaction in parallel to using transcribe stream, but we will remove the createInteraction endpoint from the server in the next few releases.
  • Improve self-hosted experience - if require auth is false, we assign a self-hosted user id serverside. This lets us hit all authenticated endpoints, letting us develop and test those locally, including the full sync loop.

@github-actions
Copy link

Resolves #448

Comment on lines +54 to +69
createbuckets:
image: minio/mc:latest
container_name: ito-minio-init
depends_on:
minio:
condition: service_healthy
entrypoint: >
/bin/sh -c "
/usr/bin/mc alias set myminio http://minio:9000 $${S3_ACCESS_KEY_ID} $${S3_SECRET_ACCESS_KEY};
/usr/bin/mc mb myminio/$${BLOB_STORAGE_BUCKET} --ignore-existing;
/usr/bin/mc mb myminio/$${TIMING_BUCKET} --ignore-existing;
/usr/bin/mc anonymous set download myminio/$${BLOB_STORAGE_BUCKET};
/usr/bin/mc anonymous set download myminio/$${TIMING_BUCKET};
echo 'Buckets created successfully';
exit 0;
"
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When running docker compose up, this script will get called and the minio buckets will get created. This makes it a little more automated to get the local stack running

TIMING_BUCKET=ito-timing-storage
AWS_REGION=us-east-1
S3_ENDPOINT=http://localhost:9000
S3_ENDPOINT=http://minio:9000
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to make this change to get my stack to work locally -- this is necessary since this is accessed within docker compose

@coderabbitai
Copy link

coderabbitai bot commented Nov 26, 2025

Walkthrough

Client: sync service start moved to run unconditionally after token processing; handleLogin now starts sync even without an access token. gRPC client: getAdvancedSettings always calls server; updateAdvancedSettings still skips server for self-hosted. SyncService: removed pushInteractions, raw_audio_id normalized to null when absent, other push/pull adjustments. Server: added getUserIdFromRequest and used it across billing, logging, and trial handlers; interaction creation refactored into createInteractionWithAudio and InteractionsRepository.create signature changed. Docker Compose: added createbuckets service, adjusted minio healthcheck and volume. Env example: S3 endpoint changed to minio:9000. Tests updated accordingly.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main objective of the PR: creating interactions directly from the transcribe stream handler, which is the primary feature change across multiple modified files.
Description check ✅ Passed The description is directly related to the changeset, explaining the three major changes: direct interaction creation from transcribeStreamHandlerV2, removal of client-side interaction pushing, and self-hosted user improvements.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ito-448

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7dea05e and e09e91c.

📒 Files selected for processing (1)
  • server/src/services/ito/interactionHelpers.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • server/src/services/ito/interactionHelpers.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: run-tests / test
  • GitHub Check: Analyze (swift)
  • GitHub Check: Analyze (rust)

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a 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 (6)
server/src/services/trial.ts (1)

8-8: Centralizing user ID lookup is good; consider self‑hosted behavior for trial routes

Using getUserIdFromRequest(request, requireAuth) here is a nice win for consistency and for the new self‑hosted user id behavior.

One thing to be aware of: when requireAuth is false, this helper returns the synthetic "self-hosted" user id, but /trial/start still goes through getUserInfoFromAuth0(userSub) and the rest of the Auth0/Stripe trial flow. In a typical self‑hosted setup where Auth0/Stripe aren’t configured or shouldn’t be used, this will just 500 rather than short‑circuiting cleanly.

If you expect self‑hosted (auth disabled) deployments to never use trials, this is fine; otherwise you may want to special‑case !requireAuth or the 'self-hosted' user id here and either block the endpoint explicitly or skip the Auth0 call with a clearer error.

Also applies to: 145-152, 278-285

server/src/services/ito/transcribeStreamV2Handler.ts (1)

32-33: Server‑side interaction creation flow looks solid; a couple of minor polish opportunities

The new flow that:

  • preserves originalTranscript before EDIT‑mode adjustment,
  • derives a human‑readable title,
  • splits asrOutput vs conditional llmOutput, and
  • uses createInteractionWithAudio with either a client‑provided or generated interaction id,

is cohesive and matches the intent to move interaction creation fully server‑side without breaking transcription on failures.

Two small refinements you might consider:

  1. Improve error log context
    In the catch around createInteractionWithAudio, include userId and finalInteractionId in the log so it’s easier to correlate failures with specific interactions:

    console.error(
      'Failed to create interaction',
      { userId, interactionId: finalInteractionId },
      error,
    )
  2. Timing vs generated interaction id
    serverTimingCollector is still keyed on the original interactionId from the client config, while storage uses finalInteractionId (which may be a freshly generated UUID). If you plan to correlate timing metrics with stored interactions, you might want to either (a) ensure clients always send an interactionId, or (b) update the timing collector usage to support the generated id once it exists.

Neither of these blocks the change; the current behavior is functionally correct.

Also applies to: 128-130, 152-201

lib/main/main.ts (1)

76-89: Unconditionally starting sync service matches the PR intent; consider guarding on token presence

Starting syncService.start() unconditionally after validating stored tokens is consistent with the goal of keeping the sync loop running, and runSync’s user?.id check should prevent work when no user is logged in.

One thing to double‑check: if a USER_PROFILE with an id remains in the store but the access token is missing/invalid (e.g., refresh failed and tokensAreValid is false), runSync will still call gRPC every 5s and depend on error handling/logging there. If this proves noisy in practice, you could add an additional guard inside runSync (e.g., skip when STORE_KEYS.ACCESS_TOKEN is absent) while still keeping the service started.

Not a blocker, just something to keep an eye on once this is exercised more.

lib/main/syncService.ts (1)

181-225: Interaction pull normalization looks good; advanced‑settings sync could be decoupled from data changes

Normalizing raw_audio_id with:

raw_audio_id: remoteInteraction.rawAudioId || null,

is a nice touch; it keeps the local Interaction shape consistent (null instead of empty string) and aligns with how you handle other nullable fields.

A related, slightly broader observation: lastSyncedAt is only advanced when processedChanges > 0 from pushes/pulls of notes/interactions/dictionary. Because syncAdvancedSettings(lastSyncedAt) doesn’t affect processedChanges, a user whose only remote state is advanced settings (no notes/interactions/dictionary yet) will see those settings re‑pulled – and advanced-settings-updated re‑emitted – on every sync pass until some other change causes lastSyncedAt to be updated.

If that ever becomes noisy, you could:

  • have syncAdvancedSettings return a boolean indicating “settings updated this run” and fold that into processedChanges, or
  • track a separate lastAdvancedSettingsSyncedAt key.

Current behavior is acceptable; this is more of a future polish consideration.

Also applies to: 251-331

server/src/services/ito/itoService.ts (1)

20-20: Good refactor to shared interaction helper; maybe add a bit more context to the error log

Switching createInteraction to:

  • convert request.rawAudio to a Buffer only when non‑empty, and
  • delegate storage + audio upload to createInteractionWithAudio

is a clean refactor and keeps all interaction/audio persistence logic in one place. The ConnectError('Failed to store interaction', Code.Internal) on failure is a reasonable public surface while you log the underlying error.

If you want easier debugging later, you could include userId and request.id in the error log here (similar to the suggestion for transcribeStreamV2Handler) so failed creates are easier to trace:

console.error('Failed to create interaction', { userId, interactionId: request.id }, error)

Functionally, though, this change looks solid.

Also applies to: 190-219

server/src/services/ito/interactionHelpers.ts (1)

1-66: Helper cleanly centralizes audio upload + interaction creation

This helper is well factored:

  • CreateInteractionParams is typed clearly and keeps the call sites simple.
  • Conditional audio upload with a generated rawAudioId and metadata, followed by a single InteractionsRepository.create call, is exactly what you want for reuse from both the gRPC service and the stream handler.
  • Logging success for both upload and DB insert will be helpful while this path is new.

If you later find log volume from these console.log calls too high in production, you could consider downgrading them to a more debug‑oriented channel or sampling them, but that’s more of an operational tuning than a code issue.

Overall, this module looks good as‑is.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ec1b3cd and a9e1bc7.

📒 Files selected for processing (15)
  • lib/auth/events.ts (1 hunks)
  • lib/clients/grpcClient.ts (0 hunks)
  • lib/main/main.ts (1 hunks)
  • lib/main/syncService.ts (1 hunks)
  • server/.env.example (1 hunks)
  • server/docker-compose.yml (2 hunks)
  • server/src/auth/authHelpers.ts (1 hunks)
  • server/src/db/repo.ts (1 hunks)
  • server/src/server.ts (1 hunks)
  • server/src/services/billing.ts (6 hunks)
  • server/src/services/ito/interactionHelpers.ts (1 hunks)
  • server/src/services/ito/itoService.ts (2 hunks)
  • server/src/services/ito/transcribeStreamV2Handler.ts (3 hunks)
  • server/src/services/logging.ts (2 hunks)
  • server/src/services/trial.ts (3 hunks)
💤 Files with no reviewable changes (1)
  • lib/clients/grpcClient.ts
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Always prefer console commands over log commands. Use console.log instead of log.info

Files:

  • server/src/auth/authHelpers.ts
  • server/src/services/ito/transcribeStreamV2Handler.ts
  • lib/main/syncService.ts
  • server/src/services/logging.ts
  • server/src/services/billing.ts
  • server/src/server.ts
  • server/src/db/repo.ts
  • server/src/services/ito/interactionHelpers.ts
  • server/src/services/trial.ts
  • server/src/services/ito/itoService.ts
  • lib/main/main.ts
  • lib/auth/events.ts
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/always.mdc)

Never use empty catch statements

Files:

  • server/src/auth/authHelpers.ts
  • server/src/services/ito/transcribeStreamV2Handler.ts
  • lib/main/syncService.ts
  • server/src/services/logging.ts
  • server/src/services/billing.ts
  • server/src/server.ts
  • server/src/db/repo.ts
  • server/src/services/ito/interactionHelpers.ts
  • server/src/services/trial.ts
  • server/src/services/ito/itoService.ts
  • lib/main/main.ts
  • lib/auth/events.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/code-conventions.mdc)

**/*.{ts,tsx}: Follow standard, idiomatic TypeScript coding practices for structure, naming, and types
Avoid adding comments unless they explain complex logic or non-obvious decisions; well-written, self-explanatory code is preferred
Do not add comments that merely restate what the code does
Rely on comprehensive tests to document the behavior and usage of code rather than extensive comments within the code itself
Use kebab-case when naming directories, TypeScript, and other files

**/*.{ts,tsx}: Prefer interfaces over types for object definitions
Use type for unions, intersections, and mapped types
NEVER use any or as any types or coercion
Leverage TypeScript's built-in utility types
Use generics for reusable type patterns
Use PascalCase for type names and interfaces
Use camelCase for variables and functions
Use UPPER_CASE for constants
Use descriptive names with auxiliary verbs (e.g., isLoading, hasError)
Prefix interfaces for React props with 'Props' (e.g., ButtonProps)
Keep type definitions close to where they're used
Export types and interfaces from dedicated type files when shared
Co-locate component props with their components
Use explicit return types for public functions
Use arrow functions for callbacks and methods
Implement proper error handling with custom error types
Use function overloads for complex type scenarios
Prefer async/await over Promises
Prefer function declarations over function expressions
Use readonly for immutable properties
Leverage discriminated unions for type safety
Use type guards for runtime type checking
Implement proper null checking
Avoid type assertions unless necessary
Handle Promise rejections properly

Files:

  • server/src/auth/authHelpers.ts
  • server/src/services/ito/transcribeStreamV2Handler.ts
  • lib/main/syncService.ts
  • server/src/services/logging.ts
  • server/src/services/billing.ts
  • server/src/server.ts
  • server/src/db/repo.ts
  • server/src/services/ito/interactionHelpers.ts
  • server/src/services/trial.ts
  • server/src/services/ito/itoService.ts
  • lib/main/main.ts
  • lib/auth/events.ts
server/**/*.{ts,js}

📄 CodeRabbit inference engine (AGENTS.md)

Backend code and database migrations should be organized in server/ using Bun

Files:

  • server/src/auth/authHelpers.ts
  • server/src/services/ito/transcribeStreamV2Handler.ts
  • server/src/services/logging.ts
  • server/src/services/billing.ts
  • server/src/server.ts
  • server/src/db/repo.ts
  • server/src/services/ito/interactionHelpers.ts
  • server/src/services/trial.ts
  • server/src/services/ito/itoService.ts
{app,lib,server}/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

{app,lib,server}/**/*.{ts,tsx,js,jsx}: Use ESLint to enforce code style and run bun run lint before submitting code
Always use console commands instead of log commands (e.g., console.log instead of log.info)

Files:

  • server/src/auth/authHelpers.ts
  • server/src/services/ito/transcribeStreamV2Handler.ts
  • lib/main/syncService.ts
  • server/src/services/logging.ts
  • server/src/services/billing.ts
  • server/src/server.ts
  • server/src/db/repo.ts
  • server/src/services/ito/interactionHelpers.ts
  • server/src/services/trial.ts
  • server/src/services/ito/itoService.ts
  • lib/main/main.ts
  • lib/auth/events.ts
{app,lib,server}/**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

Constants use SCREAMING_SNAKE_CASE naming convention

Files:

  • server/src/auth/authHelpers.ts
  • server/src/services/ito/transcribeStreamV2Handler.ts
  • lib/main/syncService.ts
  • server/src/services/logging.ts
  • server/src/services/billing.ts
  • server/src/server.ts
  • server/src/db/repo.ts
  • server/src/services/ito/interactionHelpers.ts
  • server/src/services/trial.ts
  • server/src/services/ito/itoService.ts
  • lib/main/main.ts
  • lib/auth/events.ts
{.env.example,server/.env.example}

📄 CodeRabbit inference engine (AGENTS.md)

Copy .env.example files and never commit credentials or sensitive environment variables

Files:

  • server/.env.example
lib/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Shared TypeScript modules, preload logic, and unit tests should be organized in lib/

Files:

  • lib/main/syncService.ts
  • lib/main/main.ts
  • lib/auth/events.ts
{app,lib}/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier with 2-space indent for code formatting across TypeScript and React files

Files:

  • lib/main/syncService.ts
  • lib/main/main.ts
  • lib/auth/events.ts
{app,lib}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

{app,lib}/**/*.{ts,tsx}: Components and classes use PascalCase naming convention
Hooks and utility functions use camelCase naming convention

Files:

  • lib/main/syncService.ts
  • lib/main/main.ts
  • lib/auth/events.ts
🧠 Learnings (2)
📚 Learning: 2025-11-24T19:23:48.395Z
Learnt from: CR
Repo: heyito/ito PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T19:23:48.395Z
Learning: Applies to {.env.example,server/.env.example} : Copy `.env.example` files and never commit credentials or sensitive environment variables

Applied to files:

  • server/.env.example
📚 Learning: 2025-11-24T19:23:17.133Z
Learnt from: CR
Repo: heyito/ito PR: 0
File: .cursor/rules/code-conventions.mdc:0-0
Timestamp: 2025-11-24T19:23:17.133Z
Learning: Use Auth0 for authentication

Applied to files:

  • server/src/services/billing.ts
🧬 Code graph analysis (10)
server/src/services/ito/transcribeStreamV2Handler.ts (1)
server/src/services/ito/interactionHelpers.ts (1)
  • createInteractionWithAudio (22-66)
server/src/services/logging.ts (1)
server/src/auth/authHelpers.ts (1)
  • getUserIdFromRequest (12-30)
server/src/services/billing.ts (1)
server/src/auth/authHelpers.ts (1)
  • getUserIdFromRequest (12-30)
server/src/server.ts (1)
server/src/auth/userContext.ts (1)
  • kUser (10-12)
server/src/db/repo.ts (3)
lib/main/sqlite/models.ts (1)
  • Interaction (1-14)
server/src/db/models.ts (1)
  • Interaction (11-23)
app/generated/ito_pb.ts (1)
  • Interaction (397-462)
server/src/services/ito/interactionHelpers.ts (3)
server/src/clients/s3storageClient.ts (1)
  • getStorageClient (190-196)
server/src/constants/storage.ts (1)
  • createAudioKey (3-5)
server/src/db/repo.ts (1)
  • InteractionsRepository (99-192)
server/src/services/trial.ts (1)
server/src/auth/authHelpers.ts (1)
  • getUserIdFromRequest (12-30)
server/src/services/ito/itoService.ts (1)
server/src/services/ito/interactionHelpers.ts (1)
  • createInteractionWithAudio (22-66)
lib/main/main.ts (1)
lib/main/syncService.ts (1)
  • syncService (334-334)
lib/auth/events.ts (1)
lib/main/syncService.ts (1)
  • syncService (334-334)
🪛 dotenv-linter (4.0.0)
server/.env.example

[warning] 24-24: [UnorderedKey] The S3_ENDPOINT key should go before the TIMING_BUCKET key

(UnorderedKey)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (swift)
🔇 Additional comments (10)
server/.env.example (1)

24-24: LGTM!

The change from localhost:9000 to minio:9000 is correct for Docker Compose networking, where services reference each other by service name rather than localhost.

server/docker-compose.yml (3)

14-18: Proper dependency ordering for initialization.

The use of service_completed_successfully for createbuckets ensures that MinIO buckets are initialized before the server starts.


48-52: Improved healthcheck parameters for faster startup.

The tightened healthcheck parameters (5s interval, 5s timeout, 5 retries) enable faster service initialization during local development.


54-74: Verify anonymous download permissions are appropriate for both buckets.

The createbuckets service sets anonymous download permissions on both BLOB_STORAGE_BUCKET and TIMING_BUCKET. Ensure this is intended for your use case, as it allows unauthenticated access to all bucket contents.

If these buckets contain sensitive user data or audio files, consider restricting permissions or implementing signed URLs for access control.

lib/auth/events.ts (1)

306-323: Sync service now starts unconditionally.

Starting the sync service unconditionally (rather than only when accessToken is present) aligns with the PR's goal to improve the self-hosted experience where authentication may be disabled.

server/src/services/logging.ts (1)

40-40: Centralized user ID extraction.

Using getUserIdFromRequest standardizes user identity resolution across services and supports the self-hosted development mode.

server/src/server.ts (1)

168-178: Dev-mode authentication fallback enables local testing.

The addition of a self-hosted user context when REQUIRE_AUTH is false allows developers to test authenticated endpoints locally without configuring Auth0, improving the self-hosted development experience.

server/src/services/billing.ts (1)

41-48: Standardized user extraction with proper error handling.

The use of getUserIdFromRequest with proper 401 response when the user is not authenticated follows the consistent pattern applied across all billing routes.

server/src/auth/authHelpers.ts (1)

1-30: Well-designed helper for centralized user ID extraction.

This helper cleanly centralizes the logic for extracting user IDs from requests, with appropriate fallback behavior for development mode. The JSDoc is comprehensive and the implementation is straightforward.

server/src/db/repo.ts (1)

100-124: All callers of InteractionsRepository.create use the new signature correctly.

The codebase contains only one call to InteractionsRepository.create() at server/src/services/ito/interactionHelpers.ts:53, which properly passes all required and optional fields as an object matching the new signature. No broken references exist.

Copy link

@coderabbitai coderabbitai bot left a 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

♻️ Duplicate comments (1)
lib/main/syncService.test.ts (1)

443-454: Subsequent-sync expectations align with new push/pull semantics

These assertions correctly reflect that only notes and dictionary items are pushed while notes, interactions, and dictionary items are all pulled based on the last sync timestamp; this matches the updated sync design and complements the earlier “first sync” test.

🧹 Nitpick comments (1)
lib/main/syncService.test.ts (1)

424-429: Interactions not pushed: assertions look good; consider tightening around gRPC calls

The expectations around not calling mockInteractionsTable.findModifiedSince correctly encode that interactions are no longer pushed from the client. To harden this against regressions, you could additionally assert that mockGrpcClient.createInteraction, mockGrpcClient.updateInteraction, and mockGrpcClient.deleteInteraction are not called in these “first sync” and “subsequent sync” paths.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a9e1bc7 and 7dea05e.

📒 Files selected for processing (2)
  • lib/auth/events.test.ts (2 hunks)
  • lib/main/syncService.test.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Always prefer console commands over log commands. Use console.log instead of log.info

Files:

  • lib/main/syncService.test.ts
  • lib/auth/events.test.ts
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/always.mdc)

Never use empty catch statements

Files:

  • lib/main/syncService.test.ts
  • lib/auth/events.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/code-conventions.mdc)

**/*.{ts,tsx}: Follow standard, idiomatic TypeScript coding practices for structure, naming, and types
Avoid adding comments unless they explain complex logic or non-obvious decisions; well-written, self-explanatory code is preferred
Do not add comments that merely restate what the code does
Rely on comprehensive tests to document the behavior and usage of code rather than extensive comments within the code itself
Use kebab-case when naming directories, TypeScript, and other files

**/*.{ts,tsx}: Prefer interfaces over types for object definitions
Use type for unions, intersections, and mapped types
NEVER use any or as any types or coercion
Leverage TypeScript's built-in utility types
Use generics for reusable type patterns
Use PascalCase for type names and interfaces
Use camelCase for variables and functions
Use UPPER_CASE for constants
Use descriptive names with auxiliary verbs (e.g., isLoading, hasError)
Prefix interfaces for React props with 'Props' (e.g., ButtonProps)
Keep type definitions close to where they're used
Export types and interfaces from dedicated type files when shared
Co-locate component props with their components
Use explicit return types for public functions
Use arrow functions for callbacks and methods
Implement proper error handling with custom error types
Use function overloads for complex type scenarios
Prefer async/await over Promises
Prefer function declarations over function expressions
Use readonly for immutable properties
Leverage discriminated unions for type safety
Use type guards for runtime type checking
Implement proper null checking
Avoid type assertions unless necessary
Handle Promise rejections properly

Files:

  • lib/main/syncService.test.ts
  • lib/auth/events.test.ts
lib/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Shared TypeScript modules, preload logic, and unit tests should be organized in lib/

Files:

  • lib/main/syncService.test.ts
  • lib/auth/events.test.ts
{app,lib}/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier with 2-space indent for code formatting across TypeScript and React files

Files:

  • lib/main/syncService.test.ts
  • lib/auth/events.test.ts
{app,lib,server}/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

{app,lib,server}/**/*.{ts,tsx,js,jsx}: Use ESLint to enforce code style and run bun run lint before submitting code
Always use console commands instead of log commands (e.g., console.log instead of log.info)

Files:

  • lib/main/syncService.test.ts
  • lib/auth/events.test.ts
{app,lib}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

{app,lib}/**/*.{ts,tsx}: Components and classes use PascalCase naming convention
Hooks and utility functions use camelCase naming convention

Files:

  • lib/main/syncService.test.ts
  • lib/auth/events.test.ts
{app,lib,server}/**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

Constants use SCREAMING_SNAKE_CASE naming convention

Files:

  • lib/main/syncService.test.ts
  • lib/auth/events.test.ts
🧠 Learnings (1)
📚 Learning: 2025-11-24T19:23:48.395Z
Learnt from: CR
Repo: heyito/ito PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T19:23:48.395Z
Learning: Applies to server/src/**/*.test.{ts,js} : Mock microphone, OS, and network dependencies in backend tests; avoid hitting external services

Applied to files:

  • lib/main/syncService.test.ts
  • lib/auth/events.test.ts
🧬 Code graph analysis (1)
lib/auth/events.test.ts (1)
lib/auth/events.ts (1)
  • handleLogin (306-323)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Analyze (swift)
  • GitHub Check: Analyze (rust)
🔇 Additional comments (2)
lib/auth/events.test.ts (2)

312-314: LGTM! Test correctly reflects new self-hosted behavior.

The updated assertion and comment correctly verify that the sync service now starts unconditionally, even without an access token, to support self-hosted users. This aligns with the implementation where syncService.start() is called after token processing regardless of access token presence.


344-350: LGTM! Focused test for self-hosted sync behavior.

The updated test name and comments clearly document the self-hosted scenario where the sync service starts without setting gRPC auth. While there's some overlap with the test at lines 300-315, this focused test specifically validates the new self-hosted behavior, which is appropriate given its importance to the PR objectives.

rawAudioId = uuidv4()
const audioKey = createAudioKey(userId, rawAudioId)

await storageClient.uploadObject(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should try catch this, i dont think we want to fail the whole lifecycle on the upload failing

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i see now that we handle this in the v2 handler lifecycle, but still think its appropriate to do it here as well

Copy link
Collaborator

@julgmz julgmz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small comments

@fulltimemike fulltimemike merged commit 84b5525 into dev Dec 1, 2025
9 checks passed
@fulltimemike fulltimemike deleted the ito-448 branch December 1, 2025 16:44
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants