Skip to content

Feature/244 adventure cost - #286

Open
rahulkatiayr wants to merge 1 commit into
ali-ahnaf:developfrom
rahulkatiayr:feature/244-adventure-cost
Open

Feature/244 adventure cost#286
rahulkatiayr wants to merge 1 commit into
ali-ahnaf:developfrom
rahulkatiayr:feature/244-adventure-cost

Conversation

@rahulkatiayr

@rahulkatiayr rahulkatiayr commented Jul 26, 2026

Copy link
Copy Markdown

i have implemented all api,s for adventure and adventure_items in this pr , they all are working fine i have tested them .

Summary by CodeRabbit

  • New Features
    • Added adventure planning: create, list by user, view details, update, and delete adventures with metadata (name, description, dates, visuals, completion status).
    • Added adventure items under an adventure: create, list, view, update, and delete items with amounts.
    • Introduced Wizard chat support via the application API.
  • Data & Reliability
    • Adventure and item data is now persisted and linked to the correct account.
    • Improved local development setup artifacts for consistent SQLite configuration.

@github-actions

Copy link
Copy Markdown
Contributor

Greetings, @rahulkatiayr. Thy scroll hath arrived unblemished — the runes align and no conflict bars the path. The council shall now convene over its contents, weighing each incantation by candlelight. Tarry a while, brave adventurer; we shall investigate and return to thee with our verdict.

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The pull request adds adventure and adventure-item entities, repositories, services, migrations, and authenticated Express routes. It also removes older migrations, adds SQLite rebuild migrations, adjusts middleware and TypeScript compatibility, and updates IDE, UI API, and test-support files.

Changes

Adventure management

Layer / File(s) Summary
Adventure contracts and persistence model
packages/shared/src/contracts/adventure.ts, packages/api/src/entities/*, packages/api/src/data-source.ts
Defines adventure contracts, maps adventures and items to TypeORM entities, adds User relationships, and registers the entities.
Adventure schema migration
packages/api/src/migrations/1784576018386-Migration.ts
Creates and reverts adventures and adventure_items through temporary-table copies.
Adventure persistence services
packages/api/src/repositories/adventure*.repository.ts, packages/api/src/services/adventure*.service.ts
Adds repository and service methods for adventure and adventure-item CRUD and listing operations.
Adventure API routes
packages/api/src/index.ts, packages/api/src/routes/adventure*
Adds authenticated adventure and item endpoints with Joi validation and service delegation.

Database and compatibility changes

Layer / File(s) Summary
SQLite migration rebuilds
packages/api/src/migrations/*
Removes older migrations and adds migrations that rebuild existing SQLite tables, indexes, and constraints through temporary tables.
Runtime compatibility adjustments
packages/api/src/index.ts, packages/api/src/repositories/debts.repository.ts, packages/api/src/routes/auth/sign-up.route.ts, packages/api/src/routes/debts/get-debts.route.ts
Removes cookie-parser middleware and adds TypeScript suppression directives in selected modules.

Project and UI support

Layer / File(s) Summary
IDE and package configuration
.idea/*, package.json
Adds IntelliJ ignore and SQLite datasource files and normalizes package script formatting.
UI API and validation support
packages/ui/src/lib/api/WizardApi.ts, packages/ui/src/hooks/usePushNotifications.ts, packages/api/src/tests/vaults.service.test.ts
Adds the typed wizard API, removes a helper comment, and adds an explicit User type assertion in a test helper.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant ExpressAdventureRoutes
  participant AdventureService
  participant AdventureRepository
  Client->>ExpressAdventureRoutes: Send adventure or item request
  ExpressAdventureRoutes->>AdventureService: Validate and invoke operation
  AdventureService->>AdventureRepository: Persist or query record
  AdventureRepository-->>ExpressAdventureRoutes: Return result
  ExpressAdventureRoutes-->>Client: Return response
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is only loosely related and too vague to clearly identify the main change set. Rename it to something specific like 'Add adventure and adventure item APIs'.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 19

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/api/src/services/pending-gmail-expense.service.ts (1)

24-34: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Use the shared PendingGmailExpenseDto in the API service.

The supplied context shows a duplicate local DTO in this service while packages/shared/src/contracts/pending-expenses.ts is now the canonical contract. Remove the local declaration and import the shared DTO so API and UI shapes cannot drift.

As per coding guidelines, API TypeScript must use DTOs from @expense-tracker/shared instead of defining duplicate local request or response DTOs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/services/pending-gmail-expense.service.ts` around lines 24 -
34, Replace the locally declared PendingGmailExpenseDto used by the list method
with the canonical PendingGmailExpenseDto imported from `@expense-tracker/shared`.
Remove the duplicate local DTO declaration and preserve the existing row mapping
and return shape.

Source: Coding guidelines

🟡 Minor comments (5)
.idea/codeStyles/Project.xml-10-10 (1)

10-10: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Rename FORCE_QUOTE_STYlE to FORCE_QUOTE_STYLE in both code style blocks.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.idea/codeStyles/Project.xml at line 10, Rename the misspelled
FORCE_QUOTE_STYlE option to FORCE_QUOTE_STYLE in both code style blocks,
preserving the existing value and configuration structure.
packages/api/src/repositories/debts.repository.ts-2-2 (1)

2-2: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove the // @ts-ignore`` suppressions.
@expense-tracker/shared already exports `DebtStatus` and `SignUpPayload`, so these comments are just masking type-checking.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/repositories/debts.repository.ts` at line 2, Remove the //
`@ts-ignore` suppressions at
packages/api/src/repositories/debts.repository.ts:2-2,
packages/api/src/routes/auth/sign-up.route.ts:3-3, and
packages/api/src/routes/debts/get-debts.route.ts:2-2; use the exported
DebtStatus and SignUpPayload types from `@expense-tracker/shared` directly so
type-checking remains active.
packages/ui/src/components/LogResourceModal.tsx-207-210 (1)

207-210: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Keep prompt errors visible after fallback.

The catch path sets promptResult and immediately switches to manual entry, but the result panel only renders while !manualEntry. Network/decryption/chat failures therefore disappear silently. Keep the alert visible in manual mode, or leave the prompt active and let the user choose Manual Entry.

Also applies to: 313-340

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/components/LogResourceModal.tsx` around lines 207 - 210,
Update the error handling around the prompt request in LogResourceModal so
profileApi.parseError(err) remains visible after switching to manual entry.
Adjust the result-panel render condition or fallback flow associated with
setManualEntryOverride, including the analogous path around the additional catch
block, so network, decryption, and chat errors are shown instead of hidden.
packages/ui/src/lib/api/WizardApi.ts-1-2 (1)

1-2: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Export the wizard request/response DTOs from the shared package.
@expense-tracker/shared only exports WizardPromptKey; WizardChatRequest and WizardChatResponse are missing, so this import still depends on @ts-ignore. Add those shared DTOs or import them from the correct module before removing the suppression.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/lib/api/WizardApi.ts` around lines 1 - 2, Update the shared
package exports so WizardChatRequest and WizardChatResponse are available
alongside WizardPromptKey, or import them from their correct existing shared
module; then remove the `@ts-ignore` above the WizardApi import and ensure the DTO
types resolve without suppression.
packages/api/src/routes/backup/import.route.ts-148-153 (1)

148-153: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

pushEnabled is missing from the preference schema, so it is stripped on import.

The object is typed Joi.object<UserPreferenceDto> and exports include pushEnabled (see packages/api/src/tests/backup.service.test.ts preference fixture), but with stripUnknown: { objects: true } at line 168 the value is silently dropped and never restored.

🛠️ Proposed fix
     preference: Joi.object<UserPreferenceDto>({
       showIncome: Joi.boolean().required(),
       showExpense: Joi.boolean().required(),
+      // Optional: backups exported before this preference existed omit it.
+      pushEnabled: Joi.boolean(),
       // Optional: backups exported before this preference existed omit it.
       aiTransactionEntryEnabled: Joi.boolean(),
     }).required(),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/routes/backup/import.route.ts` around lines 148 - 153,
Update the UserPreferenceDto Joi schema in the preference object to include the
pushEnabled boolean field, preserving the optionality and validation expected by
exported preference fixtures so stripUnknown does not remove it during import.
🧹 Nitpick comments (4)
packages/ui/src/app/page.tsx (1)

457-464: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Sort-order toggle's aria-label doesn't reflect the current direction.

title dynamically shows "Newest first"/"Oldest first" etc., but aria-label only ever announces "Sort by date"/"Sort by amount", losing the direction state for screen-reader users (titles are not reliably announced).

♿ Proposed fix
                   <button
                     onClick={() => setSortOrder((o) => (o === 'desc' ? 'asc' : 'desc'))}
-                    aria-label={sortField === 'date' ? 'Sort by date' : 'Sort by amount'}
+                    aria-label={
+                      sortField === 'date'
+                        ? sortOrder === 'desc'
+                          ? 'Sort by date, newest first'
+                          : 'Sort by date, oldest first'
+                        : sortOrder === 'desc'
+                          ? 'Sort by amount, largest first'
+                          : 'Sort by amount, smallest first'
+                    }
                     title={sortField === 'date' ? (sortOrder === 'desc' ? 'Newest first' : 'Oldest first') : sortOrder === 'desc' ? 'Largest first' : 'Smallest first'}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/app/page.tsx` around lines 457 - 464, Update the sort toggle
button’s aria-label in the visible button using sortField and sortOrder so it
announces both the selected field and current direction, matching the existing
title text for date and amount while preserving the toggle behavior.
packages/ui/src/components/pending-expenses/PendingExpensesPanel.tsx (1)

74-78: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider a fallback for item.vaultName.

item.subject falls back to 'No subject' when missing, but item.vaultName has no equivalent fallback, so an item without a resolved vault would render an empty Badge chip.

💡 Proposed fix
                   <Badge variant="secondary" className="text-[10px] self-start max-w-full truncate">
-                    {item.vaultName}
+                    {item.vaultName || 'Unassigned'}
                   </Badge>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/components/pending-expenses/PendingExpensesPanel.tsx` around
lines 74 - 78, Update the Badge content in the pending expense item rendering to
provide a meaningful fallback when item.vaultName is missing, matching the
existing item.subject fallback pattern. Keep the current vault name displayed
when available and use the appropriate placeholder for unresolved vaults.
packages/api/src/entities/Expense.entity.ts (1)

6-6: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Keep type checking enabled for the TransactionType import.

@ts-ignore hides every diagnostic on this import, including a missing shared-package export or invalid path. Fix the underlying export/import; if TransactionType is type-only, use import type instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/entities/Expense.entity.ts` at line 6, Remove the `@ts-ignore`
suppression on the TransactionType import and fix the underlying shared-package
export or import path so type checking remains active. If TransactionType is
only used as a type, change the import to a type-only import.
packages/shared/src/contracts/adventure.ts (1)

1-17: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Run the configured Prettier formatter. The added TypeScript uses inconsistent spacing, double quotes, and semicolon placement instead of the repository’s configured formatting.

  • packages/shared/src/contracts/adventure.ts#L1-L17: format the shared contract.
  • packages/api/src/services/adventure.service.ts#L1-L72: format the service.
  • packages/api/src/services/adventure_items.service.ts#L1-L62: format the service.
  • packages/api/src/routes/adventure.route.ts#L1-L14: format the router composition.
  • packages/api/src/routes/adventure/post-apply.route.ts#L1-L31: format the create route.
  • packages/api/src/routes/adventure/put-adventure.route.ts#L1-L33: format the update route.
  • packages/api/src/routes/adventure_items/delete-adventure.route.ts#L1-L18: format the delete route.
  • packages/api/src/routes/adventure_items/get-adventure-item.route.ts#L1-L16: format the item detail route.
  • packages/api/src/routes/adventure_items/get-all-adventure-items.route.ts#L1-L16: format the item collection route.
  • packages/api/src/routes/adventure_items/post-apply.route.ts#L1-L29: format the create-item route.
  • packages/api/src/routes/adventure_items/put-apply.route.ts#L1-L23: format the update-item route.

As per coding guidelines, “Format code with Prettier using singleQuote, trailingComma: all, and printWidth: 200.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/shared/src/contracts/adventure.ts` around lines 1 - 17, Run the
configured Prettier formatter across all affected files:
packages/shared/src/contracts/adventure.ts (lines 1-17),
packages/api/src/services/adventure.service.ts (lines 1-72),
packages/api/src/services/adventure_items.service.ts (lines 1-62),
packages/api/src/routes/adventure.route.ts (lines 1-14),
packages/api/src/routes/adventure/post-apply.route.ts (lines 1-31),
packages/api/src/routes/adventure/put-adventure.route.ts (lines 1-33),
packages/api/src/routes/adventure_items/delete-adventure.route.ts (lines 1-18),
packages/api/src/routes/adventure_items/get-adventure-item.route.ts (lines
1-16), packages/api/src/routes/adventure_items/get-all-adventure-items.route.ts
(lines 1-16), packages/api/src/routes/adventure_items/post-apply.route.ts (lines
1-29), and packages/api/src/routes/adventure_items/put-apply.route.ts (lines
1-23); apply the repository settings singleQuote, trailingComma: all, and
printWidth: 200 without changing behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/api/src/data-source.ts`:
- Around line 46-47: Run Prettier with the repository settings (singleQuote,
trailingComma: all, printWidth: 200) across the affected adventure changes.
Format the entity array in packages/api/src/data-source.ts:46-47; imports,
decorators, and properties in packages/api/src/entities/AdventureEntity.ts:1-56
and packages/api/src/entities/AdventureItemsEntity.ts:1-26; the import and
relation in packages/api/src/entities/User.entity.ts:7-39; TypeScript syntax in
packages/api/src/migrations/1784576018386-Migration.ts:1-32; declarations and
method bodies in
packages/api/src/repositories/adventure-items.repository.ts:1-43 and
packages/api/src/repositories/adventure.repository.ts:1-40; imports and route
mounts in packages/api/src/index.ts:15-70; handler syntax in
packages/api/src/routes/adventure/delete-adventure.route.ts:1-19,
get-adventure.route.ts:1-15, and get-all-adventure.route.ts:1-15; and imports
and router composition in packages/api/src/routes/adventureItems.route.ts:1-14.

In `@packages/api/src/entities/AdventureEntity.ts`:
- Around line 49-52: Use a single non-null cascading adventure FK through the
owning relation: update AdventureItemsEntity’s adventure `@ManyToOne` to own
adventure_id, make it non-null, and configure onDelete: 'CASCADE'; remove or
stop using the separate adventureId scalar. Keep AdventureEntity’s
AdventureItems relation aligned with that owner. Update
packages/api/src/migrations/1784576018386-Migration.ts lines 7-16 to create
adventure_id with a non-null constraint and ON DELETE CASCADE.

In `@packages/api/src/migrations/1784576018386-Migration.ts`:
- Around line 20-29: Update the down migration to drop the "adventure_items"
table before dropping "temporary_adventures", ensuring the child table is
removed before its renamed parent. Adjust the cleanup order around the
migration’s table renames and drops without changing the data-copy operations.

In `@packages/api/src/migrations/1784969948105-Migration.ts`:
- Around line 3-11: The migrations duplicate the same schema rebuild and
object-creation statements. Keep
packages/api/src/migrations/1784969948105-Migration.ts lines 3-11 as the single
migration containing the existing Migration1784969948105 changes; delete
packages/api/src/migrations/1784975788458-Migration.ts lines 3-11, or regenerate
that migration to contain only schema changes not already applied by the earlier
migration.

In `@packages/api/src/routes/adventure_items/post-apply.route.ts`:
- Around line 8-23: The adventureItemSchema currently requires a body
adventureId that the handler overwrites. Remove adventureId from the schema,
then validate and use the adventureId obtained from req.params as the sole
identifier when calling createAdventureItem.

In `@packages/api/src/routes/adventure.route.ts`:
- Around line 8-11: Add the get-all-adventure route to the adventure router
alongside adventureItemCreate, adventureItemUpdate, deleteAdventureItemRoute,
and getAdventureItemDetail, ensuring the collection endpoint is mounted and
reachable through this router.

In `@packages/api/src/routes/adventure/delete-adventure.route.ts`:
- Around line 13-14: Replace per-request AdventureService construction with the
shared injected service in delete-adventure.route.ts lines 13-14,
get-adventure.route.ts lines 9-10, and get-all-adventure.route.ts lines 9-10.
Export the shared repository and AdventureService once through services/index.ts
and repositories/index.ts, inject the repository through the AdventureService
constructor, and update each route to import and reuse that shared service.
- Around line 11-16: Enforce ownership for every adventure and item operation:
in packages/api/src/routes/adventure/delete-adventure.route.ts lines 11-16,
constrain AdventureService.delete to both adventureId and req.user.id; in
packages/api/src/routes/adventure/get-adventure.route.ts lines 6-11, constrain
the fetch similarly; in
packages/api/src/routes/adventure/get-all-adventure.route.ts lines 6-11, use
req.user.id or reject mismatched req.params.userId; and in
packages/api/src/routes/adventureItems.route.ts lines 8-11, ensure each item
operation verifies its parent adventure belongs to req.user before accessing it.

In `@packages/api/src/routes/adventure/get-adventure.route.ts`:
- Around line 6-13: Wrap the async route handlers in get-adventure.route.ts
(lines 6-13) and get-all-adventure.route.ts (lines 6-13) with the existing
asyncHandler utility, preserving their current service calls and responses so
rejected promises reach errorHandler.

In `@packages/api/src/services/adventure_items.service.ts`:
- Around line 26-55: Update updateAdventureItem, deleteAdventureItemById, and
findAdventureItemById to await findAdventureItem(id), throw AppError when the
awaited result is absent, and only proceed with the existing update, delete, or
return operation when the item exists.

In `@packages/api/src/services/adventure.service.ts`:
- Around line 7-11: Move repository and service construction to the shared
composition root: update AdventureService and AdventureItemsService constructors
to accept AdventureRepository and AdventureItemRepository, respectively, then
instantiate and export the shared services through services/index.ts using
repositories/index.ts dependencies. In
packages/api/src/routes/adventure/post-apply.route.ts:23-24 and
packages/api/src/routes/adventure/put-adventure.route.ts:24-25, use the exported
shared adventure service; in
packages/api/src/routes/adventure_items/delete-adventure.route.ts:11-13,
get-adventure-item.route.ts:9-10, get-all-adventure-items.route.ts:9-10,
post-apply.route.ts:21-23, and put-apply.route.ts:17-18, use the exported shared
adventure-item service instead of constructing services locally, preserving
constructor injection for unit-testability.
- Around line 31-45: Update the update method to throw AppError with status 404
when find_adventure_by_id cannot find the record, and remove the catch block
that logs and swallows errors from updateEntity or the follow-up lookup so
persistence failures propagate to asyncHandler. Preserve returning the refreshed
entity after a successful update.
- Around line 31-64: Enforce authenticated ownership across all listed sites: in
packages/api/src/services/adventure.service.ts (lines 31-64), update update,
delete, and findAdventure to accept userId and scope adventure lookups and
mutations to that owner; in packages/api/src/services/adventure_items.service.ts
(lines 26-60), accept userId and verify each item’s parent adventure belongs to
it. Pass the authenticated user ID through
packages/api/src/routes/adventure/put-adventure.route.ts (lines 19-26),
adventure_items/delete-adventure.route.ts (lines 8-14),
get-adventure-item.route.ts (lines 7-12), and put-apply.route.ts (lines 13-19);
authorize the parent adventure before listing or creating items in
get-all-adventure-items.route.ts (lines 7-12) and post-apply.route.ts (lines
15-24).

In `@packages/shared/src/contracts/adventure.ts`:
- Around line 1-17: Define shared adventure and adventure-item create/update
request DTOs and response DTOs in packages/shared/src/contracts/adventure.ts,
excluding server-owned userID from create/update inputs and adventureId from
item updates. Update the services in
packages/api/src/services/adventure.service.ts and
packages/api/src/services/adventure_items.service.ts to use the corresponding
shared DTOs instead of entity-shaped input or any. Update the listed adventure
and adventure_items route files to validate and pass those shared DTOs, without
redefining DTOs locally.

In `@packages/ui/src/app/page.tsx`:
- Around line 236-253: Update matchesSearch to handle absent item.tags before
mapping tag names, using the same nullable-tags behavior already used elsewhere
in the component. Preserve the existing title, vault, and tag search matching
for transactions and occurrences when tags are present.

In `@packages/ui/src/app/settings/ai/page.tsx`:
- Around line 86-115: Update the loadUsage callback to track an
invocation/request sequence and only commit usage, error, and loading state when
the completing request is still the latest one. Ensure older decryptKey or
fetchUsage calls cannot overwrite data or loading state after a replacement key
or refresh starts, while preserving the existing validation and error behavior.

In `@packages/ui/src/app/settings/page.tsx`:
- Line 76: Update the settings page component around useDisplaySettings to
consume its loaded state, and prevent the show-income, show-expense, and AI
transaction-entry toggles from writing or being interactive until preferences
have hydrated. Preserve normal toggle behavior once loaded, including the
affected controls in the 100-109 range.

In `@packages/ui/src/hooks/useDisplaySettings.ts`:
- Around line 18-29: Scope the settings cache in useDisplaySettings to the
active user by resetting or keying currentSettings and settingsLoaded whenever
userId changes, preventing preferences from leaking across accounts. Update the
initial-fetch failure path to broadcast or otherwise apply DEFAULT_SETTINGS and
mark settingsLoaded true, so consumers such as LogResourceModal always receive a
settled loaded state and render an appropriate entry path.

In `@packages/ui/src/hooks/usePushNotifications.ts`:
- Line 7: Update the VAPID_PUBLIC_KEY declaration in usePushNotifications to
read from process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY instead of the hardcoded
literal, and format the declaration according to Prettier.

---

Outside diff comments:
In `@packages/api/src/services/pending-gmail-expense.service.ts`:
- Around line 24-34: Replace the locally declared PendingGmailExpenseDto used by
the list method with the canonical PendingGmailExpenseDto imported from
`@expense-tracker/shared`. Remove the duplicate local DTO declaration and preserve
the existing row mapping and return shape.

---

Minor comments:
In @.idea/codeStyles/Project.xml:
- Line 10: Rename the misspelled FORCE_QUOTE_STYlE option to FORCE_QUOTE_STYLE
in both code style blocks, preserving the existing value and configuration
structure.

In `@packages/api/src/repositories/debts.repository.ts`:
- Line 2: Remove the // `@ts-ignore` suppressions at
packages/api/src/repositories/debts.repository.ts:2-2,
packages/api/src/routes/auth/sign-up.route.ts:3-3, and
packages/api/src/routes/debts/get-debts.route.ts:2-2; use the exported
DebtStatus and SignUpPayload types from `@expense-tracker/shared` directly so
type-checking remains active.

In `@packages/api/src/routes/backup/import.route.ts`:
- Around line 148-153: Update the UserPreferenceDto Joi schema in the preference
object to include the pushEnabled boolean field, preserving the optionality and
validation expected by exported preference fixtures so stripUnknown does not
remove it during import.

In `@packages/ui/src/components/LogResourceModal.tsx`:
- Around line 207-210: Update the error handling around the prompt request in
LogResourceModal so profileApi.parseError(err) remains visible after switching
to manual entry. Adjust the result-panel render condition or fallback flow
associated with setManualEntryOverride, including the analogous path around the
additional catch block, so network, decryption, and chat errors are shown
instead of hidden.

In `@packages/ui/src/lib/api/WizardApi.ts`:
- Around line 1-2: Update the shared package exports so WizardChatRequest and
WizardChatResponse are available alongside WizardPromptKey, or import them from
their correct existing shared module; then remove the `@ts-ignore` above the
WizardApi import and ensure the DTO types resolve without suppression.

---

Nitpick comments:
In `@packages/api/src/entities/Expense.entity.ts`:
- Line 6: Remove the `@ts-ignore` suppression on the TransactionType import and
fix the underlying shared-package export or import path so type checking remains
active. If TransactionType is only used as a type, change the import to a
type-only import.

In `@packages/shared/src/contracts/adventure.ts`:
- Around line 1-17: Run the configured Prettier formatter across all affected
files: packages/shared/src/contracts/adventure.ts (lines 1-17),
packages/api/src/services/adventure.service.ts (lines 1-72),
packages/api/src/services/adventure_items.service.ts (lines 1-62),
packages/api/src/routes/adventure.route.ts (lines 1-14),
packages/api/src/routes/adventure/post-apply.route.ts (lines 1-31),
packages/api/src/routes/adventure/put-adventure.route.ts (lines 1-33),
packages/api/src/routes/adventure_items/delete-adventure.route.ts (lines 1-18),
packages/api/src/routes/adventure_items/get-adventure-item.route.ts (lines
1-16), packages/api/src/routes/adventure_items/get-all-adventure-items.route.ts
(lines 1-16), packages/api/src/routes/adventure_items/post-apply.route.ts (lines
1-29), and packages/api/src/routes/adventure_items/put-apply.route.ts (lines
1-23); apply the repository settings singleQuote, trailingComma: all, and
printWidth: 200 without changing behavior.

In `@packages/ui/src/app/page.tsx`:
- Around line 457-464: Update the sort toggle button’s aria-label in the visible
button using sortField and sortOrder so it announces both the selected field and
current direction, matching the existing title text for date and amount while
preserving the toggle behavior.

In `@packages/ui/src/components/pending-expenses/PendingExpensesPanel.tsx`:
- Around line 74-78: Update the Badge content in the pending expense item
rendering to provide a meaningful fallback when item.vaultName is missing,
matching the existing item.subject fallback pattern. Keep the current vault name
displayed when available and use the appropriate placeholder for unresolved
vaults.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: a0b5159c-2578-458d-89aa-b7795038762c

📥 Commits

Reviewing files that changed from the base of the PR and between e85c3b7 and 967b44c.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (97)
  • .idea/.gitignore
  • .idea/codeStyles/Project.xml
  • .idea/codeStyles/codeStyleConfig.xml
  • .idea/modules.xml
  • .idea/pocket_pixel.iml
  • .idea/vcs.xml
  • package.json
  • packages/api/src/data-source.ts
  • packages/api/src/entities/AdventureEntity.ts
  • packages/api/src/entities/AdventureItemsEntity.ts
  • packages/api/src/entities/Expense.entity.ts
  • packages/api/src/entities/PendingGmailExpense.entity.ts
  • packages/api/src/entities/User.entity.ts
  • packages/api/src/entities/UserPreference.entity.ts
  • packages/api/src/index.ts
  • packages/api/src/migrations/1778602480669-Migration.ts
  • packages/api/src/migrations/1779000000000-AddSourceRecurringId.ts
  • packages/api/src/migrations/1779000100000-AddRecurringOccurrenceSkip.ts
  • packages/api/src/migrations/1779000200000-AddDebts.ts
  • packages/api/src/migrations/1781174119467-Migration.ts
  • packages/api/src/migrations/1782350046906-AddMonthlyBudgetToVault.ts
  • packages/api/src/migrations/1782463422810-AddDisableAiPromptToUser.ts
  • packages/api/src/migrations/1782884885022-Migration.ts
  • packages/api/src/migrations/1783358099283-Migration.ts
  • packages/api/src/migrations/1783415285262-Migration.ts
  • packages/api/src/migrations/1784576018386-Migration.ts
  • packages/api/src/migrations/1784969948105-Migration.ts
  • packages/api/src/migrations/1784975788458-Migration.ts
  • packages/api/src/migrations/1784992988030-AddSubjectToPendingGmailExpenses.ts
  • packages/api/src/migrations/1784996635799-DropIsCommittedFromExpenses.ts
  • packages/api/src/migrations/1784997323581-AddAiTransactionEntryToPreferences.ts
  • packages/api/src/migrations/Z-seed-data.ts
  • packages/api/src/repositories/adventure-items.repository.ts
  • packages/api/src/repositories/adventure.repository.ts
  • packages/api/src/repositories/debts.repository.ts
  • packages/api/src/repositories/pending-gmail-expense.repository.ts
  • packages/api/src/routes/adventure.route.ts
  • packages/api/src/routes/adventure/delete-adventure.route.ts
  • packages/api/src/routes/adventure/get-adventure.route.ts
  • packages/api/src/routes/adventure/get-all-adventure.route.ts
  • packages/api/src/routes/adventure/post-apply.route.ts
  • packages/api/src/routes/adventure/put-adventure.route.ts
  • packages/api/src/routes/adventureItems.route.ts
  • packages/api/src/routes/adventure_items/delete-adventure.route.ts
  • packages/api/src/routes/adventure_items/get-adventure-item.route.ts
  • packages/api/src/routes/adventure_items/get-all-adventure-items.route.ts
  • packages/api/src/routes/adventure_items/post-apply.route.ts
  • packages/api/src/routes/adventure_items/put-apply.route.ts
  • packages/api/src/routes/auth/sign-up.route.ts
  • packages/api/src/routes/backup/import.route.ts
  • packages/api/src/routes/debts/get-debts.route.ts
  • packages/api/src/routes/preferences/get-preferences.route.ts
  • packages/api/src/routes/preferences/put-preferences.route.ts
  • packages/api/src/routes/transactions.routes.ts
  • packages/api/src/routes/transactions/post-transaction-commit.route.ts
  • packages/api/src/routes/transactions/post-transaction-discard.route.ts
  • packages/api/src/routes/transactions/post-transaction.route.ts
  • packages/api/src/services/adventure.service.ts
  • packages/api/src/services/adventure_items.service.ts
  • packages/api/src/services/backup.service.ts
  • packages/api/src/services/gmail.service.ts
  • packages/api/src/services/pending-gmail-expense.service.ts
  • packages/api/src/services/preferences.service.ts
  • packages/api/src/services/transactions.service.ts
  • packages/api/src/tests/backup.service.test.ts
  • packages/api/src/tests/gmail.service.test.ts
  • packages/api/src/tests/pending-gmail-expense.service.test.ts
  • packages/api/src/tests/preferences.service.test.ts
  • packages/api/src/tests/transactions.service.test.ts
  • packages/shared/src/contracts/adventure.ts
  • packages/shared/src/contracts/pending-expenses.ts
  • packages/shared/src/contracts/preferences.ts
  • packages/shared/src/contracts/transactions.ts
  • packages/ui/package.json
  • packages/ui/src/__tests__/Sidebar.test.tsx
  • packages/ui/src/app/page.tsx
  • packages/ui/src/app/settings/ai/UsagePanel.tsx
  • packages/ui/src/app/settings/ai/page.tsx
  • packages/ui/src/app/settings/google-oauth/page.tsx
  • packages/ui/src/app/settings/page.tsx
  • packages/ui/src/app/stats/page.tsx
  • packages/ui/src/components/DesktopSidebar.test.tsx
  • packages/ui/src/components/DesktopSidebar.tsx
  • packages/ui/src/components/LogResourceModal.test.tsx
  • packages/ui/src/components/LogResourceModal.tsx
  • packages/ui/src/components/Sidebar.test.tsx
  • packages/ui/src/components/Sidebar.tsx
  • packages/ui/src/components/VaultExpenseChart.test.tsx
  • packages/ui/src/components/VaultExpenseChart.tsx
  • packages/ui/src/components/index.ts
  • packages/ui/src/components/pending-expenses/PendingExpensesPanel.tsx
  • packages/ui/src/hooks/useDisplaySettings.ts
  • packages/ui/src/hooks/usePushNotifications.ts
  • packages/ui/src/lib/ai/openrouter.test.ts
  • packages/ui/src/lib/ai/openrouter.ts
  • packages/ui/src/lib/api/WizardApi.ts
  • packages/ui/src/lib/chartPalette.ts
💤 Files with no reviewable changes (15)
  • packages/api/src/routes/transactions/post-transaction-discard.route.ts
  • packages/api/src/routes/transactions/post-transaction-commit.route.ts
  • packages/api/src/migrations/1778602480669-Migration.ts
  • packages/api/src/migrations/1779000000000-AddSourceRecurringId.ts
  • packages/api/src/migrations/1783358099283-Migration.ts
  • packages/api/src/migrations/1782884885022-Migration.ts
  • packages/api/src/migrations/1779000100000-AddRecurringOccurrenceSkip.ts
  • packages/api/src/migrations/1782463422810-AddDisableAiPromptToUser.ts
  • packages/api/src/migrations/Z-seed-data.ts
  • packages/api/src/migrations/1783415285262-Migration.ts
  • packages/api/src/migrations/1781174119467-Migration.ts
  • packages/api/src/migrations/1782350046906-AddMonthlyBudgetToVault.ts
  • packages/api/src/migrations/1779000200000-AddDebts.ts
  • packages/api/src/routes/transactions/post-transaction.route.ts
  • packages/api/src/routes/transactions.routes.ts

Comment on lines +46 to +47
Adventure,
AdventureItem

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Format the adventure changes with the repository Prettier settings.

  • packages/api/src/data-source.ts#L46-L47: format the entity array.
  • packages/api/src/entities/AdventureEntity.ts#L1-L56: format imports, decorators, and properties.
  • packages/api/src/entities/AdventureItemsEntity.ts#L1-L26: format imports, decorators, and properties.
  • packages/api/src/entities/User.entity.ts#L7-L39: format the import and relation declaration.
  • packages/api/src/migrations/1784576018386-Migration.ts#L1-L32: format TypeScript syntax with single quotes and standard indentation.
  • packages/api/src/repositories/adventure-items.repository.ts#L1-L43: format declarations and method bodies.
  • packages/api/src/repositories/adventure.repository.ts#L1-L40: format declarations and method bodies.
  • packages/api/src/index.ts#L15-L70: format imports and route mounts.
  • packages/api/src/routes/adventure/delete-adventure.route.ts#L1-L19: format imports and handler syntax.
  • packages/api/src/routes/adventure/get-adventure.route.ts#L1-L15: format imports and handler syntax.
  • packages/api/src/routes/adventure/get-all-adventure.route.ts#L1-L15: format imports and handler syntax.
  • packages/api/src/routes/adventureItems.route.ts#L1-L14: format imports and router composition.

As per coding guidelines, **/*.{js,jsx,ts,tsx,json,md} must be formatted with Prettier using singleQuote, trailingComma: all, and printWidth: 200.

📍 Affects 12 files
  • packages/api/src/data-source.ts#L46-L47 (this comment)
  • packages/api/src/entities/AdventureEntity.ts#L1-L56
  • packages/api/src/entities/AdventureItemsEntity.ts#L1-L26
  • packages/api/src/entities/User.entity.ts#L7-L39
  • packages/api/src/migrations/1784576018386-Migration.ts#L1-L32
  • packages/api/src/repositories/adventure-items.repository.ts#L1-L43
  • packages/api/src/repositories/adventure.repository.ts#L1-L40
  • packages/api/src/index.ts#L15-L70
  • packages/api/src/routes/adventure/delete-adventure.route.ts#L1-L19
  • packages/api/src/routes/adventure/get-adventure.route.ts#L1-L15
  • packages/api/src/routes/adventure/get-all-adventure.route.ts#L1-L15
  • packages/api/src/routes/adventureItems.route.ts#L1-L14
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/data-source.ts` around lines 46 - 47, Run Prettier with the
repository settings (singleQuote, trailingComma: all, printWidth: 200) across
the affected adventure changes. Format the entity array in
packages/api/src/data-source.ts:46-47; imports, decorators, and properties in
packages/api/src/entities/AdventureEntity.ts:1-56 and
packages/api/src/entities/AdventureItemsEntity.ts:1-26; the import and relation
in packages/api/src/entities/User.entity.ts:7-39; TypeScript syntax in
packages/api/src/migrations/1784576018386-Migration.ts:1-32; declarations and
method bodies in
packages/api/src/repositories/adventure-items.repository.ts:1-43 and
packages/api/src/repositories/adventure.repository.ts:1-40; imports and route
mounts in packages/api/src/index.ts:15-70; handler syntax in
packages/api/src/routes/adventure/delete-adventure.route.ts:1-19,
get-adventure.route.ts:1-15, and get-all-adventure.route.ts:1-15; and imports
and router composition in packages/api/src/routes/adventureItems.route.ts:1-14.

Source: Coding guidelines

Comment on lines +49 to +52
@OneToMany(() => AdventureItem,(a)=>a.adventure,{
'onDelete': 'CASCADE',
})
AdventureItems: AdventureItem[];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

sed -n '1,220p' packages/api/src/entities/AdventureEntity.ts && printf '\n---FILE---\n' && sed -n '1,220p' packages/api/src/entities/AdventureItemsEntity.ts && printf '\n---FILE---\n' && sed -n '1,220p' packages/api/src/migrations/1784576018386-Migration.ts && printf '\n---SEARCH---\n' && rg -n "adventureId|adventure_id|AdventureItems|AdventureItem|onDelete" packages/api/src -g '!**/node_modules/**'

Repository: ali-ahnaf/pocket_pixel

Length of output: 19597


🏁 Script executed:

python3 - <<'PY'
from pathlib import Path
for p in [
    Path('packages/api/src/entities/AdventureEntity.ts'),
    Path('packages/api/src/entities/AdventureItemsEntity.ts'),
    Path('packages/api/src/migrations/1784576018386-Migration.ts'),
]:
    print(f'--- {p} ---')
    print(p.read_text())
PY

Repository: ali-ahnaf/pocket_pixel

Length of output: 7333


Use one non-null cascading adventure FK.

  • packages/api/src/entities/AdventureItemsEntity.ts: adventureId is a separate scalar from the owning relation’s adventure_id, so creates can bypass the FK entirely. Move the FK to the owning @ManyToOne, make it non-null, and set onDelete: 'CASCADE' there.
  • packages/api/src/migrations/1784576018386-Migration.ts: adventure_id is still created with ON DELETE NO ACTION, so deleting an adventure will not cascade to its items.
📍 Affects 3 files
  • packages/api/src/entities/AdventureEntity.ts#L49-L52 (this comment)
  • packages/api/src/entities/AdventureItemsEntity.ts#L12-L23
  • packages/api/src/migrations/1784576018386-Migration.ts#L7-L16
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/entities/AdventureEntity.ts` around lines 49 - 52, Use a
single non-null cascading adventure FK through the owning relation: update
AdventureItemsEntity’s adventure `@ManyToOne` to own adventure_id, make it
non-null, and configure onDelete: 'CASCADE'; remove or stop using the separate
adventureId scalar. Keep AdventureEntity’s AdventureItems relation aligned with
that owner. Update packages/api/src/migrations/1784576018386-Migration.ts lines
7-16 to create adventure_id with a non-null constraint and ON DELETE CASCADE.

Comment on lines +20 to +29
await queryRunner.query(`ALTER TABLE "adventures" RENAME TO "temporary_adventures"`);
await queryRunner.query(`CREATE TABLE "adventures" ("createdAt" datetime DEFAULT (datetime('now')), "updatedAt" datetime DEFAULT (datetime('now')), "deletedAt" datetime, "id" varchar PRIMARY KEY NOT NULL, "userId" varchar(100) NOT NULL, "name" varchar(100) NOT NULL, "description" varchar(255), "icon" varchar(100), "backgroundColor" varchar(50), "startDate" date, "EndDate" date, "isComplete" boolean)`);
await queryRunner.query(`INSERT INTO "adventures"("createdAt", "updatedAt", "deletedAt", "id", "userId", "name", "description", "icon", "backgroundColor", "startDate", "EndDate", "isComplete") SELECT "createdAt", "updatedAt", "deletedAt", "id", "userId", "name", "description", "icon", "backgroundColor", "startDate", "EndDate", "isComplete" FROM "temporary_adventures"`);
await queryRunner.query(`DROP TABLE "temporary_adventures"`);
await queryRunner.query(`ALTER TABLE "adventure_items" RENAME TO "temporary_adventure_items"`);
await queryRunner.query(`CREATE TABLE "adventure_items" ("createdAt" datetime DEFAULT (datetime('now')), "updatedAt" datetime DEFAULT (datetime('now')), "deletedAt" datetime, "id" varchar PRIMARY KEY NOT NULL, "adventureId" varchar NOT NULL, "name" varchar(100) NOT NULL, "amount" decimal(10,2) NOT NULL, "adventure_id" varchar)`);
await queryRunner.query(`INSERT INTO "adventure_items"("createdAt", "updatedAt", "deletedAt", "id", "adventureId", "name", "amount", "adventure_id") SELECT "createdAt", "updatedAt", "deletedAt", "id", "adventureId", "name", "amount", "adventure_id" FROM "temporary_adventure_items"`);
await queryRunner.query(`DROP TABLE "temporary_adventure_items"`);
await queryRunner.query(`DROP TABLE "adventures"`);
await queryRunner.query(`DROP TABLE "adventure_items"`);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the migration file structure first
ast-grep outline packages/api/src/migrations/1784576018386-Migration.ts --view expanded || true

echo '--- file line count ---'
wc -l packages/api/src/migrations/1784576018386-Migration.ts

echo '--- relevant lines ---'
sed -n '1,260p' packages/api/src/migrations/1784576018386-Migration.ts

Repository: ali-ahnaf/pocket_pixel

Length of output: 5569


🏁 Script executed:

#!/bin/bash
set -euo pipefail

grep -nE 'temporary_adventures|temporary_adventure_items|FOREIGN KEY|REFERENCES|adventureId|adventure_id' packages/api/src/migrations/1784576018386-Migration.ts || true

echo '--- nearby context ---'
sed -n '1,220p' packages/api/src/migrations/1784576018386-Migration.ts

Repository: ali-ahnaf/pocket_pixel

Length of output: 8850


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find the entity/relation definitions that create the FK shape for adventures/adventure items.
rg -n --hidden --glob '!node_modules' --glob '!dist' --glob '!build' \
  'adventure_items|AdventureItem|AdventureItems|adventureId|adventures.*foreign|foreign.*adventures|REFERENCES "adventures"|REFERENCES adventures|ManyToOne|OneToMany' \
  packages/api/src || true

Repository: ali-ahnaf/pocket_pixel

Length of output: 15401


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path('packages/api/src/migrations/1784576018386-Migration.ts')
text = p.read_text()
for needle in ['foreignKeys', 'FOREIGN KEY', 'REFERENCES', 'adventure_items', 'adventures']:
    print(f'=== {needle} ===')
    for i, line in enumerate(text.splitlines(), 1):
        if needle.lower() in line.lower():
            print(f'{i}: {line}')
PY

Repository: ali-ahnaf/pocket_pixel

Length of output: 7651


🌐 Web query:

SQLite ALTER TABLE RENAME TO foreign key references updated renamed table rollback drop temporary table

💡 Result:

In SQLite, the behavior of ALTER TABLE RENAME TO regarding foreign key references depends on the version and the PRAGMA legacy_alter_table setting [1][2]. Beginning with SQLite version 3.26.0 (2018-12-01), SQLite automatically updates foreign key definitions in child tables to point to the new table name when a parent table is renamed [1][3]. This update occurs automatically unless the PRAGMA legacy_alter_table=ON setting is enabled [1][2]. Prior to version 3.26.0, this automatic update only occurred if PRAGMA foreign_keys=ON [1][2]. Key points regarding this behavior and related operations: 1. Automatic Updates: When a table is renamed, SQLite updates the text of CREATE TABLE statements (stored in the schema) for any foreign key constraints that refer to that table, ensuring the schema remains consistent [4][5]. 2. Transactional Rollback: SQLite supports transactions. If you perform ALTER TABLE RENAME TO and the operation fails or you decide to revert, you can use ROLLBACK to return the database schema to its previous state, provided the operation was performed within a transaction [6]. 3. Temporary Tables: Temporary tables exist only for the duration of the database connection. Dropping a temporary table (e.g., DROP TABLE temp_table_name) is also a database operation that can be rolled back if performed within an active transaction. 4. Schema Consistency: If you are manually recreating a table (e.g., to add a column or change a type), SQLite's ALTER TABLE RENAME mechanism is generally sufficient for basic renaming [1]. However, because SQLite lacks a DROP CONSTRAINT command, complex schema changes often require the "recreate" pattern: - Rename the old table. - Create the new table with the desired schema. - Copy data from the old table to the new table. - Drop the old table. - Note that if you are using this pattern, you may need to ensure your foreign key constraints are correctly defined in the new table's CREATE statement [7]. If you encounter issues where ALTER TABLE fails due to schema inconsistencies (e.g., views referencing missing tables), you may need to resolve those inconsistencies or use PRAGMA legacy_alter_table=ON as a temporary workaround [8][9]. Always use PRAGMA foreign_key_check after schema changes to verify that no foreign key constraints were violated [1][3].

Citations:


Drop adventure_items before temporary_adventures in down. Renaming adventures to temporary_adventures leaves adventure_items pointing at the renamed parent in SQLite, so DROP TABLE "temporary_adventures" can fail while child rows still exist.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/migrations/1784576018386-Migration.ts` around lines 20 - 29,
Update the down migration to drop the "adventure_items" table before dropping
"temporary_adventures", ensuring the child table is removed before its renamed
parent. Adjust the cleanup order around the migration’s table renames and drops
without changing the data-copy operations.

Comment on lines +3 to +11
export class Migration1784969948105 implements MigrationInterface {
name = 'Migration1784969948105'

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`CREATE TABLE "temporary_users" ("id" varchar PRIMARY KEY NOT NULL, "name" varchar(100) NOT NULL, "email" varchar(255) NOT NULL, "avatar" varchar(255) NOT NULL DEFAULT (''), "password" varchar(255) NOT NULL, "createdAt" datetime DEFAULT (datetime('now')), "updatedAt" datetime DEFAULT (datetime('now')), "deletedAt" datetime, "disableAiPrompt" boolean NOT NULL DEFAULT (0), CONSTRAINT "UQ_97672ac88f789774dd47f7c8be3" UNIQUE ("email"))`);
await queryRunner.query(`INSERT INTO "temporary_users"("id", "name", "email", "avatar", "password", "createdAt", "updatedAt", "deletedAt", "disableAiPrompt") SELECT "id", "name", "email", "avatar", "password", "createdAt", "updatedAt", "deletedAt", "disableAiPrompt" FROM "users"`);
await queryRunner.query(`DROP TABLE "users"`);
await queryRunner.query(`ALTER TABLE "temporary_users" RENAME TO "users"`);
await queryRunner.query(`CREATE TABLE "user_oauth_credentials" ("createdAt" datetime DEFAULT (datetime('now')), "updatedAt" datetime DEFAULT (datetime('now')), "deletedAt" datetime, "id" varchar PRIMARY KEY NOT NULL, "userId" varchar NOT NULL, "googleClientIdEncrypted" text NOT NULL, "googleClientSecretEncrypted" text NOT NULL, "googleAccessTokenEncrypted" text, "googleRefreshTokenEncrypted" text, "googleTokenExpiry" datetime, "googleEmail" varchar, "gmailHistoryId" varchar, "gmailWatchExpiry" datetime, CONSTRAINT "UQ_ad7506c318b5101c6f6f272168e" UNIQUE ("userId"), CONSTRAINT "REL_ad7506c318b5101c6f6f272168" UNIQUE ("userId"))`);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🔴 Critical | ⚡ Quick win

Two byte-identical migrations were committed; the second one will fail on migration:run. Both files replay the same CREATE TABLE/CREATE UNIQUE INDEX statements for user_oauth_credentials, processed_gmail_messages, vault_gmail_watchers, push_subscriptions, user_ai_credentials, and pending_gmail_expenses, so whichever runs second aborts against already-existing objects.

  • packages/api/src/migrations/1784969948105-Migration.ts#L3-L11: keep this one as the single schema-rebuild migration.
  • packages/api/src/migrations/1784975788458-Migration.ts#L3-L11: delete this file (or regenerate it so it only contains the delta not already applied by the earlier migration).
📍 Affects 2 files
  • packages/api/src/migrations/1784969948105-Migration.ts#L3-L11 (this comment)
  • packages/api/src/migrations/1784975788458-Migration.ts#L3-L11
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/migrations/1784969948105-Migration.ts` around lines 3 - 11,
The migrations duplicate the same schema rebuild and object-creation statements.
Keep packages/api/src/migrations/1784969948105-Migration.ts lines 3-11 as the
single migration containing the existing Migration1784969948105 changes; delete
packages/api/src/migrations/1784975788458-Migration.ts lines 3-11, or regenerate
that migration to contain only schema changes not already applied by the earlier
migration.

Comment thread packages/api/src/routes/adventure_items/post-apply.route.ts
Comment on lines +236 to +253
const normalizedSearch = searchQuery.trim().toLowerCase();
const matchesSearch = (item: { title: string | null; vault: { name: string } | null; tags: { name: string }[] }) => {
if (!normalizedSearch) return true;
const haystack = [item.title ?? '', item.vault?.name ?? '', ...item.tags.map((t) => t.name)];
return haystack.some((value) => value.toLowerCase().includes(normalizedSearch));
};
const filteredDrops = transactions
.filter((t) => matchesVault(t.vaultId) && matchesTag(t.tags))
.filter((t) => matchesVault(t.vaultId) && matchesTag(t.tags) && matchesSearch(t))
.slice()
.sort((a, b) => (dateSortOrder === 'desc' ? b.date.localeCompare(a.date) || b.updatedAt.localeCompare(a.updatedAt) : a.date.localeCompare(b.date) || a.updatedAt.localeCompare(b.updatedAt)));
const filteredOccurrences = occurrences.filter((o) => matchesVault(o.vaultId) && matchesTag(o.tags));
.sort((a, b) => {
const byDate = sortOrder === 'desc' ? b.date.localeCompare(a.date) || b.updatedAt.localeCompare(a.updatedAt) : a.date.localeCompare(b.date) || a.updatedAt.localeCompare(b.updatedAt);
if (sortField === 'amount') {
const byAmount = sortOrder === 'desc' ? b.amount - a.amount : a.amount - b.amount;
return byAmount || byDate;
}
return byDate;
});
const filteredOccurrences = occurrences.filter((o) => matchesVault(o.vaultId) && matchesTag(o.tags) && matchesSearch(o));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Unguarded item.tags.map will throw for any transaction/occurrence without tags.

matchesSearch spreads item.tags.map((t) => t.name) without a null-safe guard, while item.vault?.name on the same line is guarded. This same file already treats tags as possibly absent elsewhere (tx.tags?.length ? <TagChips tags={tx.tags} /> : ... at line 611). Since matchesSearch only short-circuits on an empty search box (if (!normalizedSearch) return true;), as soon as a user types anything, any transaction/occurrence with tags undefined will throw Cannot read properties of undefined (reading 'map'), crashing the render for the whole list.

matchesTag avoids this because it short-circuits via selectedTagFilter.length === 0 || before ever touching .tags; matchesSearch has no equivalent guard.

🐛 Proposed fix
-    const haystack = [item.title ?? '', item.vault?.name ?? '', ...item.tags.map((t) => t.name)];
+    const haystack = [item.title ?? '', item.vault?.name ?? '', ...(item.tags ?? []).map((t) => t.name)];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const normalizedSearch = searchQuery.trim().toLowerCase();
const matchesSearch = (item: { title: string | null; vault: { name: string } | null; tags: { name: string }[] }) => {
if (!normalizedSearch) return true;
const haystack = [item.title ?? '', item.vault?.name ?? '', ...item.tags.map((t) => t.name)];
return haystack.some((value) => value.toLowerCase().includes(normalizedSearch));
};
const filteredDrops = transactions
.filter((t) => matchesVault(t.vaultId) && matchesTag(t.tags))
.filter((t) => matchesVault(t.vaultId) && matchesTag(t.tags) && matchesSearch(t))
.slice()
.sort((a, b) => (dateSortOrder === 'desc' ? b.date.localeCompare(a.date) || b.updatedAt.localeCompare(a.updatedAt) : a.date.localeCompare(b.date) || a.updatedAt.localeCompare(b.updatedAt)));
const filteredOccurrences = occurrences.filter((o) => matchesVault(o.vaultId) && matchesTag(o.tags));
.sort((a, b) => {
const byDate = sortOrder === 'desc' ? b.date.localeCompare(a.date) || b.updatedAt.localeCompare(a.updatedAt) : a.date.localeCompare(b.date) || a.updatedAt.localeCompare(b.updatedAt);
if (sortField === 'amount') {
const byAmount = sortOrder === 'desc' ? b.amount - a.amount : a.amount - b.amount;
return byAmount || byDate;
}
return byDate;
});
const filteredOccurrences = occurrences.filter((o) => matchesVault(o.vaultId) && matchesTag(o.tags) && matchesSearch(o));
const normalizedSearch = searchQuery.trim().toLowerCase();
const matchesSearch = (item: { title: string | null; vault: { name: string } | null; tags: { name: string }[] }) => {
if (!normalizedSearch) return true;
const haystack = [item.title ?? '', item.vault?.name ?? '', ...(item.tags ?? []).map((t) => t.name)];
return haystack.some((value) => value.toLowerCase().includes(normalizedSearch));
};
const filteredDrops = transactions
.filter((t) => matchesVault(t.vaultId) && matchesTag(t.tags) && matchesSearch(t))
.slice()
.sort((a, b) => {
const byDate = sortOrder === 'desc' ? b.date.localeCompare(a.date) || b.updatedAt.localeCompare(a.updatedAt) : a.date.localeCompare(b.date) || a.updatedAt.localeCompare(b.updatedAt);
if (sortField === 'amount') {
const byAmount = sortOrder === 'desc' ? b.amount - a.amount : a.amount - b.amount;
return byAmount || byDate;
}
return byDate;
});
const filteredOccurrences = occurrences.filter((o) => matchesVault(o.vaultId) && matchesTag(o.tags) && matchesSearch(o));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/app/page.tsx` around lines 236 - 253, Update matchesSearch to
handle absent item.tags before mapping tag names, using the same nullable-tags
behavior already used elsewhere in the component. Preserve the existing title,
vault, and tag search matching for transactions and occurrences when tags are
present.

Comment thread packages/ui/src/app/settings/ai/page.tsx

export default function SettingsPage() {
const { showIncome, showExpense, setShowIncome, setShowExpense } = useDisplaySettings();
const { showIncome, showExpense, aiTransactionEntryEnabled, setShowIncome, setShowExpense, setAiTransactionEntryEnabled } = useDisplaySettings();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Prevent writes before preferences hydrate.

The new toggle is enabled while useDisplaySettings is still loading. A user interaction in that window persists the default/cached full settings object and can overwrite their stored preferences. Consume loaded here and disable or defer all preference toggles until hydration finishes.

Also applies to: 100-109

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/app/settings/page.tsx` at line 76, Update the settings page
component around useDisplaySettings to consume its loaded state, and prevent the
show-income, show-expense, and AI transaction-entry toggles from writing or
being interactive until preferences have hydrated. Preserve normal toggle
behavior once loaded, including the affected controls in the 100-109 range.

Comment on lines 18 to 29
// Module-level cache so components mounted after the first fetch render the
// last-known settings immediately instead of flashing the defaults.
let currentSettings: DisplaySettings = DEFAULT_SETTINGS;
// Consumers that branch on a setting (not just mask a value) need to know
// whether `currentSettings` is still the defaults or a real server response.
let settingsLoaded = false;

const broadcast = (settings: DisplaySettings): void => {
currentSettings = settings;
settingsLoaded = true;
// Notify every hook instance in this tab (React state isn't shared across them).
window.dispatchEvent(new Event(SETTINGS_EVENT));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Scope and settle the settings cache per user.

currentSettings and settingsLoaded survive sign-out/account switches, so a subsequent user can temporarily see—and persist—another user’s preferences. Also, a failed initial fetch leaves loaded false forever, causing LogResourceModal to render neither entry path. Reset or key the cache by userId, and settle failures to DEFAULT_SETTINGS with loaded: true.

Also applies to: 54-62

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/hooks/useDisplaySettings.ts` around lines 18 - 29, Scope the
settings cache in useDisplaySettings to the active user by resetting or keying
currentSettings and settingsLoaded whenever userId changes, preventing
preferences from leaking across accounts. Update the initial-fetch failure path
to broadcast or otherwise apply DEFAULT_SETTINGS and mark settingsLoaded true,
so consumers such as LogResourceModal always receive a settled loaded state and
render an appropriate entry path.

Comment thread packages/ui/src/hooks/usePushNotifications.ts Outdated
@rahulkatiayr
rahulkatiayr force-pushed the feature/244-adventure-cost branch from 370b855 to 070e58e Compare July 26, 2026 11:02

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
packages/api/src/index.ts (1)

15-15: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Format the new import with Prettier.

Line 15 is missing the semicolon used by the surrounding TypeScript file. Please run Prettier on the changed file.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/index.ts` at line 15, Format the adventureRouter import in
the module alongside the surrounding TypeScript imports, adding the semicolon
required by the repository’s Prettier configuration; run Prettier on the changed
file.

Source: Coding guidelines

packages/api/src/migrations/1784975788458-Migration.ts (1)

136-139: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Redundant users rebuild in down().

Lines 109-112 already restore users to exactly this definition; this second rebuild is a no-op table copy (the mirror of the redundant up() block at lines 7-10). Removing it shortens rollback and avoids a needless full-table copy.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/migrations/1784975788458-Migration.ts` around lines 136 -
139, Remove the redundant users table rebuild from the migration’s down()
method: delete the rename, CREATE TABLE, INSERT, and DROP statements involving
temporary_users, while preserving the earlier users restoration block that
already reestablishes the required schema.
packages/api/src/migrations/1784576018386-Migration.ts (1)

1-1: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use the repository’s Prettier quote style.

Change "typeorm" to 'typeorm'.

As per coding guidelines, **/*.{js,jsx,ts,tsx,json,md} must be formatted with Prettier using singleQuote, trailingComma: all, and printWidth: 200.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/migrations/1784576018386-Migration.ts` at line 1, Update the
import in MigrationInterface to use the repository’s Prettier single-quote
style, changing the typeorm module specifier from double quotes to single
quotes.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/api/src/migrations/1784975788458-Migration.ts`:
- Around line 7-10: Remove the initial users-table rebuild consisting of the
temporary_users creation, INSERT ... SELECT, users drop, and temporary_users
rename queries. Keep the later users migration rebuild unchanged so existing
OAuth users with nullable passwords remain supported.

---

Nitpick comments:
In `@packages/api/src/index.ts`:
- Line 15: Format the adventureRouter import in the module alongside the
surrounding TypeScript imports, adding the semicolon required by the
repository’s Prettier configuration; run Prettier on the changed file.

In `@packages/api/src/migrations/1784576018386-Migration.ts`:
- Line 1: Update the import in MigrationInterface to use the repository’s
Prettier single-quote style, changing the typeorm module specifier from double
quotes to single quotes.

In `@packages/api/src/migrations/1784975788458-Migration.ts`:
- Around line 136-139: Remove the redundant users table rebuild from the
migration’s down() method: delete the rename, CREATE TABLE, INSERT, and DROP
statements involving temporary_users, while preserving the earlier users
restoration block that already reestablishes the required schema.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: a16acf0e-2437-42ae-b548-55f197381efb

📥 Commits

Reviewing files that changed from the base of the PR and between 967b44c and 070e58e.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (49)
  • .idea/.gitignore
  • .idea/codeStyles/Project.xml
  • .idea/codeStyles/codeStyleConfig.xml
  • .idea/modules.xml
  • .idea/pocket_pixel.iml
  • .idea/vcs.xml
  • package.json
  • packages/api/src/data-source.ts
  • packages/api/src/entities/AdventureEntity.ts
  • packages/api/src/entities/AdventureItemsEntity.ts
  • packages/api/src/entities/Expense.entity.ts
  • packages/api/src/entities/User.entity.ts
  • packages/api/src/index.ts
  • packages/api/src/migrations/1778602480669-Migration.ts
  • packages/api/src/migrations/1779000000000-AddSourceRecurringId.ts
  • packages/api/src/migrations/1779000100000-AddRecurringOccurrenceSkip.ts
  • packages/api/src/migrations/1779000200000-AddDebts.ts
  • packages/api/src/migrations/1781174119467-Migration.ts
  • packages/api/src/migrations/1782350046906-AddMonthlyBudgetToVault.ts
  • packages/api/src/migrations/1782463422810-AddDisableAiPromptToUser.ts
  • packages/api/src/migrations/1782884885022-Migration.ts
  • packages/api/src/migrations/1783358099283-Migration.ts
  • packages/api/src/migrations/1783415285262-Migration.ts
  • packages/api/src/migrations/1784576018386-Migration.ts
  • packages/api/src/migrations/1784969948105-Migration.ts
  • packages/api/src/migrations/1784975788458-Migration.ts
  • packages/api/src/migrations/Z-seed-data.ts
  • packages/api/src/repositories/adventure-items.repository.ts
  • packages/api/src/repositories/adventure.repository.ts
  • packages/api/src/repositories/debts.repository.ts
  • packages/api/src/routes/adventure.route.ts
  • packages/api/src/routes/adventure/delete-adventure.route.ts
  • packages/api/src/routes/adventure/get-adventure.route.ts
  • packages/api/src/routes/adventure/get-all-adventure.route.ts
  • packages/api/src/routes/adventure/post-apply.route.ts
  • packages/api/src/routes/adventure/put-adventure.route.ts
  • packages/api/src/routes/adventureItems.route.ts
  • packages/api/src/routes/adventure_items/delete-adventure.route.ts
  • packages/api/src/routes/adventure_items/get-adventure-item.route.ts
  • packages/api/src/routes/adventure_items/get-all-adventure-items.route.ts
  • packages/api/src/routes/adventure_items/post-apply.route.ts
  • packages/api/src/routes/adventure_items/put-apply.route.ts
  • packages/api/src/routes/auth/sign-up.route.ts
  • packages/api/src/routes/debts/get-debts.route.ts
  • packages/api/src/services/adventure.service.ts
  • packages/api/src/services/adventure_items.service.ts
  • packages/shared/src/contracts/adventure.ts
  • packages/ui/src/hooks/usePushNotifications.ts
  • packages/ui/src/lib/api/WizardApi.ts
💤 Files with no reviewable changes (11)
  • packages/api/src/migrations/1782884885022-Migration.ts
  • packages/api/src/migrations/1779000100000-AddRecurringOccurrenceSkip.ts
  • packages/api/src/migrations/1783415285262-Migration.ts
  • packages/api/src/migrations/Z-seed-data.ts
  • packages/api/src/migrations/1783358099283-Migration.ts
  • packages/api/src/migrations/1779000000000-AddSourceRecurringId.ts
  • packages/api/src/migrations/1782463422810-AddDisableAiPromptToUser.ts
  • packages/api/src/migrations/1782350046906-AddMonthlyBudgetToVault.ts
  • packages/api/src/migrations/1779000200000-AddDebts.ts
  • packages/api/src/migrations/1778602480669-Migration.ts
  • packages/api/src/migrations/1781174119467-Migration.ts
🚧 Files skipped from review as they are similar to previous changes (34)
  • .idea/.gitignore
  • .idea/modules.xml
  • .idea/vcs.xml
  • .idea/codeStyles/codeStyleConfig.xml
  • packages/api/src/routes/auth/sign-up.route.ts
  • packages/ui/src/lib/api/WizardApi.ts
  • packages/shared/src/contracts/adventure.ts
  • .idea/pocket_pixel.iml
  • packages/api/src/entities/AdventureItemsEntity.ts
  • packages/api/src/routes/adventure.route.ts
  • packages/api/src/routes/adventure_items/delete-adventure.route.ts
  • packages/api/src/repositories/adventure.repository.ts
  • packages/api/src/routes/adventure_items/put-apply.route.ts
  • packages/api/src/routes/adventure/delete-adventure.route.ts
  • packages/api/src/routes/adventureItems.route.ts
  • packages/api/src/routes/adventure_items/get-adventure-item.route.ts
  • packages/api/src/routes/adventure_items/get-all-adventure-items.route.ts
  • packages/api/src/routes/debts/get-debts.route.ts
  • packages/api/src/repositories/adventure-items.repository.ts
  • packages/api/src/repositories/debts.repository.ts
  • .idea/codeStyles/Project.xml
  • packages/api/src/routes/adventure/get-all-adventure.route.ts
  • packages/api/src/data-source.ts
  • packages/api/src/routes/adventure/get-adventure.route.ts
  • packages/api/src/services/adventure_items.service.ts
  • packages/api/src/services/adventure.service.ts
  • packages/api/src/routes/adventure_items/post-apply.route.ts
  • packages/api/src/migrations/1784969948105-Migration.ts
  • packages/api/src/entities/User.entity.ts
  • packages/api/src/routes/adventure/post-apply.route.ts
  • packages/api/src/routes/adventure/put-adventure.route.ts
  • packages/api/src/entities/AdventureEntity.ts
  • package.json
  • packages/api/src/entities/Expense.entity.ts

Comment on lines +7 to +10
await queryRunner.query(`CREATE TABLE "temporary_users" ("id" varchar PRIMARY KEY NOT NULL, "name" varchar(100) NOT NULL, "email" varchar(255) NOT NULL, "avatar" varchar(255) NOT NULL DEFAULT (''), "password" varchar(255) NOT NULL, "createdAt" datetime DEFAULT (datetime('now')), "updatedAt" datetime DEFAULT (datetime('now')), "deletedAt" datetime, "disableAiPrompt" boolean NOT NULL DEFAULT (0), CONSTRAINT "UQ_97672ac88f789774dd47f7c8be3" UNIQUE ("email"))`);
await queryRunner.query(`INSERT INTO "temporary_users"("id", "name", "email", "avatar", "password", "createdAt", "updatedAt", "deletedAt", "disableAiPrompt") SELECT "id", "name", "email", "avatar", "password", "createdAt", "updatedAt", "deletedAt", "disableAiPrompt" FROM "users"`);
await queryRunner.query(`DROP TABLE "users"`);
await queryRunner.query(`ALTER TABLE "temporary_users" RENAME TO "users"`);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
fd -t f 'User.entity.ts' packages/api/src --exec cat -n {}
rg -n --type=ts -C2 'password' packages/api/src/routes/auth/sign-up.route.ts
rg -n --type=ts '"password" varchar' packages/api/src/migrations

Repository: ali-ahnaf/pocket_pixel

Length of output: 9376


🏁 Script executed:

#!/bin/bash
sed -n '1,45p;100,145p' packages/api/src/migrations/1784975788458-Migration.ts | cat -n

Repository: ali-ahnaf/pocket_pixel

Length of output: 20246


Drop the first users rebuild.
Lines 7-10 briefly make password NOT NULL, but the migration later rebuilds users with password nullable again. Existing OAuth users can have NULL passwords, so this INSERT ... SELECT can fail and block the migration. The first rebuild is redundant and should be removed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/migrations/1784975788458-Migration.ts` around lines 7 - 10,
Remove the initial users-table rebuild consisting of the temporary_users
creation, INSERT ... SELECT, users drop, and temporary_users rename queries.
Keep the later users migration rebuild unchanged so existing OAuth users with
nullable passwords remain supported.

@rahulkatiayr
rahulkatiayr force-pushed the feature/244-adventure-cost branch 2 times, most recently from f7660a4 to 8f78f38 Compare July 26, 2026 12:45

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
packages/api/src/routes/debts/get-debts.route.ts (1)

2-2: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Drop the @ts-ignore and use a type-only import. DebtStatus is already exported from @expense-tracker/shared, and this usage is type-only, so the suppression is unnecessary.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/routes/debts/get-debts.route.ts` at line 2, Remove the
`@ts-ignore` suppression and update the relevant import in the debts route to a
type-only import for the exported DebtStatus symbol from
`@expense-tracker/shared`. Preserve the existing runtime imports and type usage.
packages/api/src/index.ts (1)

15-15: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Format the changed TypeScript with the required Prettier configuration.

These lines mix semicolon styles and contain spacing inconsistent with Prettier ('... ' ,requireAuth,adventureRouter). Run Prettier with singleQuote, trailingComma: all, and printWidth: 200 before merging.

Proposed normalization
-import adventureRouter from './routes/adventure.route'
+import adventureRouter from './routes/adventure.route';

-import adventureItemsRoute from './routes/adventureItems.route';
+import adventureItemsRoute from './routes/adventureItems.route';

-app.use('/api/users/:userId/adventures' ,requireAuth,adventureRouter)
+app.use('/api/users/:userId/adventures', requireAuth, adventureRouter);

Also applies to: 32-32, 66-67

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/index.ts` at line 15, Format the changed TypeScript in
packages/api/src/index.ts with Prettier using singleQuote, trailingComma: all,
and printWidth: 200, including the import at the top and the affected route
declarations around lines 32 and 66-67. Normalize semicolons, spacing, and comma
formatting without changing behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/api/src/index.ts`:
- Line 15: Format the changed TypeScript in packages/api/src/index.ts with
Prettier using singleQuote, trailingComma: all, and printWidth: 200, including
the import at the top and the affected route declarations around lines 32 and
66-67. Normalize semicolons, spacing, and comma formatting without changing
behavior.

In `@packages/api/src/routes/debts/get-debts.route.ts`:
- Line 2: Remove the `@ts-ignore` suppression and update the relevant import in
the debts route to a type-only import for the exported DebtStatus symbol from
`@expense-tracker/shared`. Preserve the existing runtime imports and type usage.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 2bdd3455-6017-4f6a-820b-ed770cd3934d

📥 Commits

Reviewing files that changed from the base of the PR and between 070e58e and 8f78f38.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (50)
  • .idea/.gitignore
  • .idea/codeStyles/Project.xml
  • .idea/codeStyles/codeStyleConfig.xml
  • .idea/modules.xml
  • .idea/pocket_pixel.iml
  • .idea/vcs.xml
  • package.json
  • packages/api/src/data-source.ts
  • packages/api/src/entities/AdventureEntity.ts
  • packages/api/src/entities/AdventureItemsEntity.ts
  • packages/api/src/entities/Expense.entity.ts
  • packages/api/src/entities/User.entity.ts
  • packages/api/src/index.ts
  • packages/api/src/migrations/1778602480669-Migration.ts
  • packages/api/src/migrations/1779000000000-AddSourceRecurringId.ts
  • packages/api/src/migrations/1779000100000-AddRecurringOccurrenceSkip.ts
  • packages/api/src/migrations/1779000200000-AddDebts.ts
  • packages/api/src/migrations/1781174119467-Migration.ts
  • packages/api/src/migrations/1782350046906-AddMonthlyBudgetToVault.ts
  • packages/api/src/migrations/1782463422810-AddDisableAiPromptToUser.ts
  • packages/api/src/migrations/1782884885022-Migration.ts
  • packages/api/src/migrations/1783358099283-Migration.ts
  • packages/api/src/migrations/1783415285262-Migration.ts
  • packages/api/src/migrations/1784576018386-Migration.ts
  • packages/api/src/migrations/1784969948105-Migration.ts
  • packages/api/src/migrations/1784975788458-Migration.ts
  • packages/api/src/migrations/Z-seed-data.ts
  • packages/api/src/repositories/adventure-items.repository.ts
  • packages/api/src/repositories/adventure.repository.ts
  • packages/api/src/repositories/debts.repository.ts
  • packages/api/src/routes/adventure.route.ts
  • packages/api/src/routes/adventure/delete-adventure.route.ts
  • packages/api/src/routes/adventure/get-adventure.route.ts
  • packages/api/src/routes/adventure/get-all-adventure.route.ts
  • packages/api/src/routes/adventure/post-apply.route.ts
  • packages/api/src/routes/adventure/put-adventure.route.ts
  • packages/api/src/routes/adventureItems.route.ts
  • packages/api/src/routes/adventure_items/delete-adventure.route.ts
  • packages/api/src/routes/adventure_items/get-adventure-item.route.ts
  • packages/api/src/routes/adventure_items/get-all-adventure-items.route.ts
  • packages/api/src/routes/adventure_items/post-apply.route.ts
  • packages/api/src/routes/adventure_items/put-apply.route.ts
  • packages/api/src/routes/auth/sign-up.route.ts
  • packages/api/src/routes/debts/get-debts.route.ts
  • packages/api/src/services/adventure.service.ts
  • packages/api/src/services/adventure_items.service.ts
  • packages/api/src/tests/vaults.service.test.ts
  • packages/shared/src/contracts/adventure.ts
  • packages/ui/src/hooks/usePushNotifications.ts
  • packages/ui/src/lib/api/WizardApi.ts
💤 Files with no reviewable changes (12)
  • packages/api/src/migrations/1782350046906-AddMonthlyBudgetToVault.ts
  • packages/api/src/migrations/1779000000000-AddSourceRecurringId.ts
  • packages/api/src/migrations/1779000100000-AddRecurringOccurrenceSkip.ts
  • packages/api/src/migrations/1779000200000-AddDebts.ts
  • packages/api/src/migrations/1782884885022-Migration.ts
  • packages/api/src/migrations/1781174119467-Migration.ts
  • packages/api/src/migrations/1778602480669-Migration.ts
  • packages/ui/src/hooks/usePushNotifications.ts
  • packages/api/src/migrations/1783415285262-Migration.ts
  • packages/api/src/migrations/1783358099283-Migration.ts
  • packages/api/src/migrations/1782463422810-AddDisableAiPromptToUser.ts
  • packages/api/src/migrations/Z-seed-data.ts
🚧 Files skipped from review as they are similar to previous changes (35)
  • packages/api/src/routes/auth/sign-up.route.ts
  • packages/api/src/routes/adventure.route.ts
  • .idea/codeStyles/codeStyleConfig.xml
  • packages/api/src/routes/adventureItems.route.ts
  • .idea/vcs.xml
  • packages/api/src/routes/adventure_items/get-all-adventure-items.route.ts
  • packages/ui/src/lib/api/WizardApi.ts
  • .idea/pocket_pixel.iml
  • packages/api/src/routes/adventure/get-all-adventure.route.ts
  • packages/shared/src/contracts/adventure.ts
  • .idea/modules.xml
  • packages/api/src/repositories/debts.repository.ts
  • packages/api/src/entities/AdventureItemsEntity.ts
  • packages/api/src/routes/adventure_items/put-apply.route.ts
  • packages/api/src/services/adventure_items.service.ts
  • packages/api/src/data-source.ts
  • packages/api/src/routes/adventure_items/get-adventure-item.route.ts
  • packages/api/src/routes/adventure_items/post-apply.route.ts
  • packages/api/src/repositories/adventure.repository.ts
  • .idea/codeStyles/Project.xml
  • .idea/.gitignore
  • packages/api/src/entities/User.entity.ts
  • packages/api/src/routes/adventure/delete-adventure.route.ts
  • packages/api/src/routes/adventure_items/delete-adventure.route.ts
  • package.json
  • packages/api/src/repositories/adventure-items.repository.ts
  • packages/api/src/entities/Expense.entity.ts
  • packages/api/src/routes/adventure/get-adventure.route.ts
  • packages/api/src/routes/adventure/put-adventure.route.ts
  • packages/api/src/migrations/1784969948105-Migration.ts
  • packages/api/src/entities/AdventureEntity.ts
  • packages/api/src/services/adventure.service.ts
  • packages/api/src/routes/adventure/post-apply.route.ts
  • packages/api/src/migrations/1784576018386-Migration.ts
  • packages/api/src/migrations/1784975788458-Migration.ts

Comment thread .idea/codeStyles/codeStyleConfig.xml Outdated

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

please discard the .idea folder changes

icon:string | null;
backgroundColor: string | null;
startDate:string | null;
EndDate:string | null;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

casing inconsistent

import { Vault } from './Vault.entity';
import { TransactionTag } from './TransactionTag.entity';
import { BaseEntity } from './BaseEntity';
// @ts-ignore

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

changes not required here.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

you should not remove any existing migration files.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

as per your code changes, there should be only 1 new migration file added

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

discard changes here

@rahulkatiayr

Copy link
Copy Markdown
Author

@ali-ahnaf ohk let me do improvements

@rahulkatiayr
rahulkatiayr force-pushed the feature/244-adventure-cost branch from 5fd8389 to 25d58b9 Compare July 28, 2026 18:10

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/api/src/index.ts (1)

15-15: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Format the changed TypeScript with Prettier.

These lines mix semicolons, spacing, and statement styles. Run the configured Prettier formatter using singleQuote, trailingComma: all, and printWidth: 200.

As per coding guidelines, TypeScript files must be formatted with those Prettier settings.

Also applies to: 32-32, 66-67

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/index.ts` at line 15, Format the changed TypeScript
statements in the module imports and the sections around the referenced lines
using the configured Prettier settings: singleQuote, trailingComma: all, and
printWidth: 200. Apply formatting consistently without changing behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/api/src/index.ts`:
- Line 15: Format the changed TypeScript statements in the module imports and
the sections around the referenced lines using the configured Prettier settings:
singleQuote, trailingComma: all, and printWidth: 200. Apply formatting
consistently without changing behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f8e33571-9b90-46ea-8a63-4ffc29615f35

📥 Commits

Reviewing files that changed from the base of the PR and between 5fd8389 and 25d58b9.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (44)
  • .idea/.gitignore
  • .idea/dataSources.xml
  • package.json
  • packages/api/src/data-source.ts
  • packages/api/src/entities/AdventureEntity.ts
  • packages/api/src/entities/AdventureItemsEntity.ts
  • packages/api/src/entities/User.entity.ts
  • packages/api/src/index.ts
  • packages/api/src/migrations/1778602480669-Migration.ts
  • packages/api/src/migrations/1779000000000-AddSourceRecurringId.ts
  • packages/api/src/migrations/1779000100000-AddRecurringOccurrenceSkip.ts
  • packages/api/src/migrations/1779000200000-AddDebts.ts
  • packages/api/src/migrations/1781174119467-Migration.ts
  • packages/api/src/migrations/1782350046906-AddMonthlyBudgetToVault.ts
  • packages/api/src/migrations/1782884885022-Migration.ts
  • packages/api/src/migrations/1783358099283-Migration.ts
  • packages/api/src/migrations/1783415285262-Migration.ts
  • packages/api/src/migrations/1784576018386-Migration.ts
  • packages/api/src/migrations/1784969948105-Migration.ts
  • packages/api/src/migrations/1784975788458-Migration.ts
  • packages/api/src/migrations/Z-seed-data.ts
  • packages/api/src/repositories/adventure-items.repository.ts
  • packages/api/src/repositories/adventure.repository.ts
  • packages/api/src/repositories/debts.repository.ts
  • packages/api/src/routes/adventure.route.ts
  • packages/api/src/routes/adventure/delete-adventure.route.ts
  • packages/api/src/routes/adventure/get-adventure.route.ts
  • packages/api/src/routes/adventure/get-all-adventure.route.ts
  • packages/api/src/routes/adventure/post-apply.route.ts
  • packages/api/src/routes/adventure/put-adventure.route.ts
  • packages/api/src/routes/adventureItems.route.ts
  • packages/api/src/routes/adventure_items/delete-adventure.route.ts
  • packages/api/src/routes/adventure_items/get-adventure-item.route.ts
  • packages/api/src/routes/adventure_items/get-all-adventure-items.route.ts
  • packages/api/src/routes/adventure_items/post-apply.route.ts
  • packages/api/src/routes/adventure_items/put-apply.route.ts
  • packages/api/src/routes/auth/sign-up.route.ts
  • packages/api/src/routes/debts/get-debts.route.ts
  • packages/api/src/services/adventure.service.ts
  • packages/api/src/services/adventure_items.service.ts
  • packages/api/src/tests/vaults.service.test.ts
  • packages/shared/src/contracts/adventure.ts
  • packages/ui/src/hooks/usePushNotifications.ts
  • packages/ui/src/lib/api/WizardApi.ts
💤 Files with no reviewable changes (11)
  • packages/api/src/migrations/1782884885022-Migration.ts
  • packages/api/src/migrations/1783358099283-Migration.ts
  • packages/api/src/migrations/1779000100000-AddRecurringOccurrenceSkip.ts
  • packages/api/src/migrations/1781174119467-Migration.ts
  • packages/api/src/migrations/1779000000000-AddSourceRecurringId.ts
  • packages/api/src/migrations/Z-seed-data.ts
  • packages/ui/src/hooks/usePushNotifications.ts
  • packages/api/src/migrations/1782350046906-AddMonthlyBudgetToVault.ts
  • packages/api/src/migrations/1779000200000-AddDebts.ts
  • packages/api/src/migrations/1783415285262-Migration.ts
  • packages/api/src/migrations/1778602480669-Migration.ts
🚧 Files skipped from review as they are similar to previous changes (32)
  • .idea/dataSources.xml
  • packages/api/src/routes/auth/sign-up.route.ts
  • packages/api/src/routes/debts/get-debts.route.ts
  • packages/api/src/routes/adventure_items/get-adventure-item.route.ts
  • packages/api/src/routes/adventureItems.route.ts
  • packages/api/src/routes/adventure_items/post-apply.route.ts
  • packages/api/src/data-source.ts
  • packages/ui/src/lib/api/WizardApi.ts
  • packages/api/src/routes/adventure/get-adventure.route.ts
  • packages/api/src/routes/adventure_items/get-all-adventure-items.route.ts
  • packages/shared/src/contracts/adventure.ts
  • packages/api/src/routes/adventure/put-adventure.route.ts
  • packages/api/src/repositories/adventure.repository.ts
  • packages/api/src/repositories/adventure-items.repository.ts
  • packages/api/src/entities/User.entity.ts
  • packages/api/src/routes/adventure_items/delete-adventure.route.ts
  • packages/api/src/entities/AdventureEntity.ts
  • .idea/.gitignore
  • packages/api/src/services/adventure_items.service.ts
  • packages/api/src/entities/AdventureItemsEntity.ts
  • packages/api/src/routes/adventure_items/put-apply.route.ts
  • packages/api/src/tests/vaults.service.test.ts
  • packages/api/src/services/adventure.service.ts
  • packages/api/src/routes/adventure/delete-adventure.route.ts
  • package.json
  • packages/api/src/repositories/debts.repository.ts
  • packages/api/src/routes/adventure/get-all-adventure.route.ts
  • packages/api/src/routes/adventure.route.ts
  • packages/api/src/routes/adventure/post-apply.route.ts
  • packages/api/src/migrations/1784969948105-Migration.ts
  • packages/api/src/migrations/1784576018386-Migration.ts
  • packages/api/src/migrations/1784975788458-Migration.ts

@rahulkatiayr
rahulkatiayr force-pushed the feature/244-adventure-cost branch 2 times, most recently from a4ac014 to c793fe1 Compare July 28, 2026 20:26
@rahulkatiayr
rahulkatiayr force-pushed the feature/244-adventure-cost branch from 8d31161 to ef66215 Compare July 29, 2026 13:34
@rahulkatiayr

Copy link
Copy Markdown
Author

@ali-ahnaf please check and merge i have resolved the issues

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants