Skip to content

feat: prospective points on user#256

Merged
hmbanan666 merged 1 commit intomainfrom
prospective-points
Oct 31, 2025
Merged

feat: prospective points on user#256
hmbanan666 merged 1 commit intomainfrom
prospective-points

Conversation

@hmbanan666
Copy link
Copy Markdown
Collaborator

@hmbanan666 hmbanan666 commented Oct 31, 2025

Summary by CodeRabbit

  • New Features

    • Added a "Награды" (Rewards) section to main navigation.
    • Introduced prospective points display on the home page.
    • Added account creation timeline tracking.
    • Launched new rewards page for future points system.
  • User Interface Improvements

    • Enhanced avatar styling with borders.
    • Replaced detailed view lists with streamlined view counter display.

@hmbanan666 hmbanan666 self-assigned this Oct 31, 2025
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Oct 31, 2025

Walkthrough

Introduces a new "Awards" (Награды) feature across the hub-telegram app, including new UI components to display prospective points and account creation days, a new /points page, updated navigation routing, store state additions, database schema expansion, and a Russian pluralization utility function.

Changes

Cohort / File(s) Summary
New prospective display components
apps/hub-telegram/app/components/ProspectiveBlock.vue, ProspectiveDays.vue, ProspectivePoints.vue
Introduces three new Vue components: ProspectiveBlock wires userStore data to display prospective points and days; ProspectiveDays computes and renders days since account creation with Russian pluralization; ProspectivePoints displays points count with pluralized Russian label.
Page updates
apps/hub-telegram/app/pages/index.vue, points/index.vue, flow/[itemId]/index.vue
Replaces level text with ProspectiveBlock on home page; increases avatar size with border styling; adds new /points page with placeholder content; replaces "Посмотрели" avatar section with inline view counter icon in flow item header.
Navigation & store state
apps/hub-telegram/app/composables/useNavigation.ts, stores/user.ts
Updates main navigation to route "Награды" to /points with coins icon; adds createdAt and prospectivePoints reactive state to user store with API population during update.
Utilities & schema
apps/hub-telegram/shared/utils/helpers.ts, packages/database/src/tables.ts
Adds pluralizationRu utility function for Russian plural form selection; adds prospectivePoints integer column (default 0) to users table.

Sequence Diagram

sequenceDiagram
    participant User
    participant Page as pages/index.vue
    participant Block as ProspectiveBlock
    participant Store as userStore
    participant Points as ProspectivePoints
    participant Days as ProspectiveDays

    User->>Page: View home page
    Page->>Block: Mount ProspectiveBlock
    Block->>Store: useUserStore()
    Store-->>Block: {prospectivePoints, createdAt}
    Block->>Points: Pass prospectivePoints
    Points-->>Block: Render points display
    Block->>Days: Pass createdAt
    Days-->>Block: Render days display
    Block-->>User: Display prospective info
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

  • Pluralization function: Verify Russian language rules are correctly implemented
  • Store synchronization: Confirm createdAt and prospectivePoints are populated from API responses consistently
  • Component integration: Ensure ProspectiveBlock properly binds store data to child components
  • Database migration: Verify prospectivePoints column default and null constraints align with store initialization

Poem

🐰 Hopping through points and days so bright,
Prospective rewards shine in sight,
Balancing scores with Russian flair,
New features bloom with thoughtful care,
The awards page awaits—coming soon, I declare!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "feat: prospective points on user" directly describes the main objective of the changeset: introducing a prospective points feature tied to the user system. The title is concise, uses standard commit conventions, and clearly conveys the primary change without being vague or overly broad. The implementation includes new Vue components, store updates, database schema changes, and UI integrations all centered around displaying prospective points to users. A teammate scanning the repository history would immediately understand that this PR adds a prospective points feature for the user context.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch prospective-points

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
15.0% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (3)
apps/hub-telegram/app/pages/points/index.vue (1)

1-16: Placeholder page pending implementation.

The rewards page currently displays "Будет чуть позже" (coming soon). This appears intentional for this PR.

Do you want me to help implement the rewards functionality, or will this be addressed in a follow-up PR?

apps/hub-telegram/app/components/ProspectiveDays.vue (1)

15-16: Consider caching the days calculation.

The days computed uses Date.now(), which means it will recalculate on every access. If real-time updates aren't needed, consider computing it once:

-const date = computed(() => new Date(createdAt))
-const days = computed(() => Math.floor((Date.now() - date.value.getTime()) / 86400000))
+const date = new Date(createdAt)
+const days = Math.floor((Date.now() - date.getTime()) / 86400000)

Alternatively, if you want the day count to update at midnight, use a ref with an interval.

apps/hub-telegram/shared/utils/helpers.ts (1)

3-17: Consider consolidating duplicate pluralizationRu implementations.

The exact same pluralizationRu function exists in apps/atrium-telegram/shared/utils/helpers.ts. Consider moving it to a shared package that both apps can import to avoid duplication and ensure consistency.

Possible locations:

  • Create a shared packages/i18n-utils package
  • Use a monorepo shared utilities package

This would make maintenance easier and prevent drift between implementations.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ed1d5a1 and 829e037.

📒 Files selected for processing (10)
  • apps/hub-telegram/app/components/ProspectiveBlock.vue (1 hunks)
  • apps/hub-telegram/app/components/ProspectiveDays.vue (1 hunks)
  • apps/hub-telegram/app/components/ProspectivePoints.vue (1 hunks)
  • apps/hub-telegram/app/composables/useNavigation.ts (1 hunks)
  • apps/hub-telegram/app/pages/flow/[itemId]/index.vue (1 hunks)
  • apps/hub-telegram/app/pages/index.vue (1 hunks)
  • apps/hub-telegram/app/pages/points/index.vue (1 hunks)
  • apps/hub-telegram/app/stores/user.ts (3 hunks)
  • apps/hub-telegram/shared/utils/helpers.ts (1 hunks)
  • packages/database/src/tables.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/hub-telegram/shared/utils/helpers.ts (1)
apps/atrium-telegram/shared/utils/helpers.ts (1)
  • pluralizationRu (5-19)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (9)
apps/hub-telegram/app/pages/flow/[itemId]/index.vue (1)

30-35: LGTM! Clean UI simplification.

The inline view counter is more compact than the previous avatars section. Note that this trades detailed viewer information for a cleaner interface.

apps/hub-telegram/app/pages/index.vue (2)

7-7: LGTM! Avatar styling enhanced.

The increased size and primary border improve visual prominence.


12-12: LGTM! Dynamic user data integration.

Replacing the hardcoded "Ты 1 уровня" text with the ProspectiveBlock component enables dynamic display of user points and days data from the store.

apps/hub-telegram/app/composables/useNavigation.ts (1)

16-20: LGTM! Navigation correctly configured.

The rewards navigation item is properly set up with the appropriate path, icon, and title.

apps/hub-telegram/app/components/ProspectivePoints.vue (1)

1-14: LGTM! Clean implementation.

The component correctly uses Russian pluralization for the points label. Ensure pluralizationRu is auto-imported (as noted in ProspectiveDays.vue review).

packages/database/src/tables.ts (1)

29-29: I need to gather more information about the database setup and migrations structure.

Now let me check the actual directory structure and configuration files:

Verify that the migration file for prospectivePoints has been generated and included in this PR.

Drizzle requires SQL migration files to be generated from schema changes using drizzle-kit generate, then applied to the database with drizzle-kit migrate. The search found no migration files containing prospective_points—only the schema file where the column was defined. If you're using a code-first approach where your TypeScript schema is the source of truth, you'll need to apply that schema to the database either through Drizzle or external migration tools.

Ensure you've run the migration generation step (e.g., drizzle-kit generate) and that the resulting migration files are committed to this PR.

apps/hub-telegram/app/components/ProspectiveBlock.vue (1)

12-14: LGTM!

The script setup is clean and correctly uses the composition API.

apps/hub-telegram/app/stores/user.ts (2)

19-20: LGTM!

The new reactive properties are correctly initialized with appropriate types and default values.


106-107: LGTM!

The new properties are correctly exposed in the store's public API, making them available for components to consume.

Comment on lines +1 to +10
<template>
<div class="grid grid-cols-2 gap-2">
<NuxtLink to="/points">
<ActiveCard>
<ProspectivePoints :points="userStore.prospectivePoints" />
</ActiveCard>
</NuxtLink>
<ProspectiveDays :created-at="userStore.createdAt as string" />
</div>
</template>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Handle null createdAt to prevent runtime errors.

Line 8 uses a type assertion as string on userStore.createdAt, which is typed as string | null in the store (line 19 of user.ts). If the user data hasn't loaded yet or the API response is missing this field, createdAt will be null, causing the ProspectiveDays component to receive null instead of a string. This could lead to runtime errors or unexpected behavior.

Consider one of these solutions:

Solution 1: Add a conditional render

 <template>
-  <div class="grid grid-cols-2 gap-2">
+  <div v-if="userStore.createdAt" class="grid grid-cols-2 gap-2">
     <NuxtLink to="/points">
       <ActiveCard>
         <ProspectivePoints :points="userStore.prospectivePoints" />
       </ActiveCard>
     </NuxtLink>
-    <ProspectiveDays :created-at="userStore.createdAt as string" />
+    <ProspectiveDays :created-at="userStore.createdAt" />
   </div>
 </template>

Solution 2: Update ProspectiveDays to handle null

If ProspectiveDays should handle the null case internally, update its prop type to accept string | null and remove the type assertion:

-    <ProspectiveDays :created-at="userStore.createdAt as string" />
+    <ProspectiveDays :created-at="userStore.createdAt" />
📝 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
<template>
<div class="grid grid-cols-2 gap-2">
<NuxtLink to="/points">
<ActiveCard>
<ProspectivePoints :points="userStore.prospectivePoints" />
</ActiveCard>
</NuxtLink>
<ProspectiveDays :created-at="userStore.createdAt as string" />
</div>
</template>
<template>
<div v-if="userStore.createdAt" class="grid grid-cols-2 gap-2">
<NuxtLink to="/points">
<ActiveCard>
<ProspectivePoints :points="userStore.prospectivePoints" />
</ActiveCard>
</NuxtLink>
<ProspectiveDays :created-at="userStore.createdAt" />
</div>
</template>
Suggested change
<template>
<div class="grid grid-cols-2 gap-2">
<NuxtLink to="/points">
<ActiveCard>
<ProspectivePoints :points="userStore.prospectivePoints" />
</ActiveCard>
</NuxtLink>
<ProspectiveDays :created-at="userStore.createdAt as string" />
</div>
</template>
<template>
<div class="grid grid-cols-2 gap-2">
<NuxtLink to="/points">
<ActiveCard>
<ProspectivePoints :points="userStore.prospectivePoints" />
</ActiveCard>
</NuxtLink>
<ProspectiveDays :created-at="userStore.createdAt" />
</div>
</template>
🤖 Prompt for AI Agents
In apps/hub-telegram/app/components/ProspectiveBlock.vue around lines 1-10, the
template force-casts userStore.createdAt to string even though the store types
it as string | null; update the component to avoid passing null: either (A) add
a conditional render or fallback in the template (e.g. only render
<ProspectiveDays> when userStore.createdAt is non-null or pass a safe fallback
like an empty string) or (B) change ProspectiveDays to accept string | null by
updating its prop type and internal logic to handle the null case; pick one
approach and implement the corresponding change so no forced type assertion
remains and null is safely handled.

Comment on lines +1 to +17
<template>
<Section class="motion-preset-slide-down motion-delay-400">
<div class="flex flex-col gap-2">
<UIcon name="i-lucide-calendar-check-2" class="size-8 text-primary" />
<p class="text-base/5">
Вы с нами уже <span class="font-bold">{{ days }} {{ pluralizationRu(days, ['день', 'дня', 'дней']) }}</span>
</p>
</div>
</Section>
</template>

<script setup lang="ts">
const { createdAt } = defineProps<{ createdAt: string }>()

const date = computed(() => new Date(createdAt))
const days = computed(() => Math.floor((Date.now() - date.value.getTime()) / 86400000))
</script>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify pluralizationRu is auto-imported.

The pluralizationRu function is used but not explicitly imported. Ensure your build configuration auto-imports it, or add an explicit import.


🏁 Script executed:

#!/bin/bash
# Check auto-imports configuration
cat apps/hub-telegram/nuxt.config.ts | grep -A 10 "imports"

Length of output: 0


I need to investigate further. The initial grep produced no output. Let me check if the file exists and explore how auto-imports are configured in this project.


🏁 Script executed:

#!/bin/bash
# Find nuxt config file and check its structure
echo "=== Looking for nuxt config files ==="
find . -name "nuxt.config.*" -type f 2>/dev/null | head -20

echo ""
echo "=== Full content of apps/hub-telegram/nuxt.config.ts ==="
if [ -f "apps/hub-telegram/nuxt.config.ts" ]; then
  cat "apps/hub-telegram/nuxt.config.ts"
else
  echo "File not found"
fi

echo ""
echo "=== Search for pluralizationRu definition ==="
rg -n "pluralizationRu" --type ts --type vue -C 2

Length of output: 1868


The config extends '@roll-stack/ui', which could provide auto-imports. Let me search for the pluralizationRu function definition and check the shared UI package:


🏁 Script executed:

#!/bin/bash
# Search for pluralizationRu definition across all files
echo "=== Search for pluralizationRu definition ==="
rg -n "pluralizationRu" -C 2

echo ""
echo "=== Check @roll-stack/ui structure (packages/ui) ==="
find packages/ui -type f -name "*.ts" -o -name "*.js" | grep -E "(util|composable|index)" | head -20

echo ""
echo "=== Search for pluralizationRu in packages/ui ==="
rg -n "pluralizationRu" packages/ui/ -C 2

echo ""
echo "=== Check for auto-import configuration in packages/ui ==="
cat packages/ui/nuxt.config.ts 2>/dev/null || echo "Not found"

Length of output: 14994


I found that pluralizationRu is defined in apps/hub-telegram/shared/utils/helpers.ts. Let me check how other components import it and verify the auto-import configuration:


🏁 Script executed:

#!/bin/bash
# Check how ProspectivePoints.vue (which also uses pluralizationRu) handles imports
echo "=== Full ProspectivePoints.vue file ==="
cat apps/hub-telegram/app/components/ProspectivePoints.vue

echo ""
echo "=== Check for app.config.ts ==="
cat apps/hub-telegram/app.config.ts 2>/dev/null || echo "Not found"

echo ""
echo "=== Look for plugins or auto-import setup ==="
find apps/hub-telegram -name "*.ts" -o -name "*.js" | xargs grep -l "auto.*import\|import.*auto" 2>/dev/null | head -10

echo ""
echo "=== Check for tsconfig/path aliases ==="
cat apps/hub-telegram/tsconfig.json 2>/dev/null | grep -A 10 "paths" || echo "No tsconfig found or no paths"

Length of output: 658


Let me check if there are any explicit imports of pluralizationRu anywhere in the codebase:


🏁 Script executed:

#!/bin/bash
# Check if pluralizationRu is explicitly imported anywhere
echo "=== Files that import pluralizationRu ==="
rg -n "import.*pluralizationRu" 

echo ""
echo "=== Check root nuxt.config.ts ==="
cat nuxt.config.ts 2>/dev/null || echo "Not found"

echo ""
echo "=== Check package.json for nuxt config ==="
cat package.json | grep -A 20 '"nuxt"'

echo ""
echo "=== Check for .nuxtrc or nuxt.config.* in root ==="
find . -maxdepth 1 -name "nuxt.config.*" -o -name ".nuxtrc"

Length of output: 182


Add explicit import for pluralizationRu from shared utils.

The function is used on line 6 but not imported. It's defined in apps/hub-telegram/shared/utils/helpers.ts and located outside standard Nuxt auto-import directories. Add an explicit import statement at the top of the <script setup> block:

import { pluralizationRu } from '#shared/utils/helpers'

Verify the correct import path alias for your shared utilities.

🤖 Prompt for AI Agents
In apps/hub-telegram/app/components/ProspectiveDays.vue around lines 1 to 17,
the template uses pluralizationRu on line 6 but the <script setup> block does
not import it; add an explicit import of pluralizationRu from the shared utils
before using it (e.g. import { pluralizationRu } from the correct shared
alias/path) and ensure the import path matches your project aliases (e.g.
'#shared/utils/helpers') so the function is available in the template.

Comment on lines +54 to +55
createdAt.value = data.createdAt
prospectivePoints.value = data.prospectivePoints
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Validate API response fields to prevent type inconsistencies.

The code assigns data.createdAt and data.prospectivePoints without verifying these fields exist in the API response. If the API doesn't return these fields (e.g., during a deployment where the backend hasn't been updated yet, or due to an API error), the values will be set to undefined, violating the type contracts (string | null and number).

Apply this diff to add safe fallbacks:

       focusedTaskId.value = data.focusedTaskId
-      createdAt.value = data.createdAt
-      prospectivePoints.value = data.prospectivePoints
+      createdAt.value = data.createdAt ?? null
+      prospectivePoints.value = data.prospectivePoints ?? 0
📝 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
createdAt.value = data.createdAt
prospectivePoints.value = data.prospectivePoints
focusedTaskId.value = data.focusedTaskId
createdAt.value = data.createdAt ?? null
prospectivePoints.value = data.prospectivePoints ?? 0
🤖 Prompt for AI Agents
In apps/hub-telegram/app/stores/user.ts around lines 54-55, the code assigns
data.createdAt and data.prospectivePoints directly which can set undefined and
violate the expected types; update the assignments to validate types and provide
safe fallbacks: set createdAt.value to the string if typeof data.createdAt ===
'string' else null, and set prospectivePoints.value to the numeric value if
typeof data.prospectivePoints === 'number' else a safe default (e.g., 0).

@hmbanan666 hmbanan666 merged commit 0d13456 into main Oct 31, 2025
7 of 8 checks passed
@hmbanan666 hmbanan666 deleted the prospective-points branch October 31, 2025 13:34
@coderabbitai coderabbitai bot mentioned this pull request Oct 31, 2025
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.

1 participant