Skip to content

chore: message intro with button#155

Merged
hmbanan666 merged 1 commit into
mainfrom
atrium-button
Sep 15, 2025
Merged

chore: message intro with button#155
hmbanan666 merged 1 commit into
mainfrom
atrium-button

Conversation

@hmbanan666

@hmbanan666 hmbanan666 commented Sep 15, 2025

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Telegram posts now include an “Open Atrium” button that deep-links into the app using a compact start parameter.
    • Start screen supports a new “flow” start key for direct navigation; invalid params route to home.
  • UI

    • Staff list: tighter spacing, wider tiles, bold multi-line names above status with consistent truncation.
    • Start screen loader: increased size and primary color.
  • Content

    • Telegram messages send a short teaser instead of the full text, with the full content available inside the app.

@hmbanan666 hmbanan666 self-assigned this Sep 15, 2025
@coderabbitai

coderabbitai Bot commented Sep 15, 2025

Copy link
Copy Markdown

Walkthrough

Updates a Telegram Atrium component’s layout/text, enhances start parameter parsing in the start page to support a new flow/ route, and revises the daily-report task to create a flow item, send a teaser to Telegram, and attach an inline button linking to the Atrium app via startapp data.

Changes

Cohort / File(s) Summary
Atrium Telegram UI layout/text
apps/atrium-telegram/app/components/StaffBlock.vue
Reduced inner gap, widened user tiles, added bold user.name above status, applied line-clamp to name and status. No data/behavior changes.
Atrium Telegram start parameter handling
apps/atrium-telegram/app/pages/startapp.vue
Loader icon now uses size-8 and text-primary. Added parsing for startapp key/value with a separator. Routes epic/, new flow/, else redirects to '/'.
Daily report teaser and deep link
apps/web-app/server/tasks/ai/daily-report.ts
Captures created flow item, builds startapp data as flow{separator}{id}, sends a teaser (first 40 words) to Telegram with an inline “Open Atrium” button linking to t.me/.../app?startapp=..., stores full content in flow item.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant CRON as Scheduler
  participant Task as daily-report.ts
  participant Repo as repository.flow
  participant TG as Telegram API
  participant User as Telegram User

  CRON->>Task: Run daily report
  Task->>Repo: createItem(finalMessage as description)
  Repo-->>Task: flowItem(id)
  Note right of Task: Build startapp data: "flow{separator}{id}"
  Task->>TG: sendMessage(prepared teaser, inline button → t.me/.../app?startapp=flow{sep}{id})
  TG-->>User: Teaser with “Open Atrium” button
Loading
sequenceDiagram
  autonumber
  participant User as Telegram User
  participant TG as Telegram App
  participant Atrium as startapp.vue Router
  participant Pages as /epic/* or /flow/*

  User->>TG: Tap “Open Atrium” (startapp=key{sep}value)
  TG->>Atrium: Launch with tgWebAppStartParam
  Atrium->>Atrium: Parse key/value by separator
  alt key=="epic" and value
    Atrium->>Pages: Navigate to /epic/{value}
  else key=="flow" and value
    Atrium->>Pages: Navigate to /flow/{value}
  else missing/invalid
    Atrium->>Pages: Navigate to /
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • chore: navigation rework #152 — Also edits daily-report.ts, modifying the flow item title; intersects with this PR’s creation and usage of the flow item for startapp links.
  • feat: atrium telegram bot #77 — Introduces Atrium Telegram bot start/startapp flow; directly related to this PR’s startapp URL construction and parsing.
  • chore: tasks rework #88 — Adjusts guards/logging in daily-report.ts; overlaps the same task file changed here for teaser and deep-link behavior.

Poem

A hop, a tap, a teaser’s glow,
I thump the ground—let data flow!
A secret path in startapp’s string,
To flows we scurry—click the ring.
Names now bold, the tiles aligned,
Carrot-links to Atrium—nicely signed.
🥕✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "chore: message intro with button" succinctly identifies the primary change—sending a shortened message preview with an inline button that opens the Atrium app—implemented in the daily-report task and tied to startapp flow handling. It is concise, on-topic, and clear for a teammate scanning PRs. It appropriately focuses on the main behavior change and does not need to list minor UI tweaks in other files.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch atrium-button

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


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

@hmbanan666 hmbanan666 merged commit fefb28e into main Sep 15, 2025
7 of 8 checks passed
@hmbanan666 hmbanan666 deleted the atrium-button branch September 15, 2025 14:11

@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: 2

🧹 Nitpick comments (6)
apps/atrium-telegram/app/components/StaffBlock.vue (2)

7-9: Make the tile accessible and keyboard-activatable; also verify w-18 utility.

  • The clickable div lacks button semantics and keyboard handlers. Add role/tabindex and Enter/Space handlers.
  • Please confirm w-18 exists in your utility scale (Tailwind default doesn’t include 18; if using UnoCSS/Windi or a custom scale, it’s fine).
       <div
         v-for="user in allUsers"
         :key="user.id"
-        class="w-18 flex flex-col gap-1 justify-start items-center scroll-ml-6 snap-start motion-preset-slide-right"
-        @click="handleClick(user.id)"
+        class="w-18 flex flex-col gap-1 justify-start items-center scroll-ml-6 snap-start motion-preset-slide-right"
+        role="button"
+        tabindex="0"
+        :aria-label="`Открыть Telegram ${user.name} ${user.surname ?? ''}`"
+        @click="handleClick(user.id)"
+        @keydown.enter.prevent="handleClick(user.id)"
+        @keydown.space.prevent="handleClick(user.id)"
       >

33-35: Guard against invalid/missing dates in the offline label.

If onlineAt is falsy/invalid, new Date('') can yield “Invalid Date” in some helpers. Add a safe fallback.

-        <p class="text-xs/3 text-muted text-center line-clamp-2">
-          {{ user.isOnline ? 'Онлайн' : useTimeAgoIntl(new Date(user.onlineAt ?? '')) }}
-        </p>
+        <p class="text-xs/3 text-muted text-center line-clamp-2">
+          {{ user.isOnline ? 'Онлайн' : (user.onlineAt ? useTimeAgoIntl(new Date(user.onlineAt)) : '—') }}
+        </p>
apps/atrium-telegram/app/pages/startapp.vue (3)

11-20: Return after redirects to avoid multiple navigations.

Without return, execution continues and may trigger additional navigation.

   if (!key || !value) {
-    await navigateTo('/')
+    return await navigateTo('/')
   }

21-28: Handle unknown keys with a default route; ensure single-exit navigation.

Add an explicit fallback for unexpected keys and return on every branch.

-  if (key === 'epic') {
-    await navigateTo(`/epic/${value}`)
-  }
-
-  if (key === 'flow') {
-    await navigateTo(`/flow/${value}`)
-  }
+  if (key === 'epic') {
+    return await navigateTo(`/epic/${value}`)
+  } else if (key === 'flow') {
+    return await navigateTo(`/flow/${value}`)
+  } else {
+    return await navigateTo('/')
+  }

7-7: Extract shared separator constant into a single module

Duplicate const separator = 'zzzzz' found in:

  • apps/web-app/server/tasks/ai/daily-report.ts
  • apps/web-app/server/api/beacon/epic/comment.post.ts
  • apps/atrium-telegram/app/pages/startapp.vue
  • apps/storefront-telegram/app/pages/startapp.vue

Move the constant to a shared package (e.g., packages/shared or packages/constants), export a named constant, and import it in these files to prevent subtle mismatches.

apps/web-app/server/tasks/ai/daily-report.ts (1)

71-81: Use the encoded param and avoid hardcoding the bot username.

  • Switch to startAppParam (encoded).
  • Consider moving sushi_atrium_bot to runtime config (e.g., telegram.botUsername) to prevent drift.
-      await useAtriumBot().api.sendMessage(telegram.teamGroupId, preparedMessage, {
+      await useAtriumBot().api.sendMessage(telegram.teamGroupId, preparedMessage, {
         link_preview_options: {
           is_disabled: true,
         },
         reply_markup: {
           inline_keyboard: [[{
             text: '👉 Открыть Атриум',
-            url: `https://t.me/sushi_atrium_bot/app?startapp=${startAppData}`,
+            url: `https://t.me/sushi_atrium_bot/app?startapp=${startAppParam}`,
           }]],
         },
       })

Optional config-driven URL (outside this diff):

// useRuntimeConfig().telegram.botUsername
const appUrl = `https://t.me/${telegram.botUsername}/app?startapp=${startAppParam}`
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b2244a9 and 74b0bd9.

📒 Files selected for processing (3)
  • apps/atrium-telegram/app/components/StaffBlock.vue (2 hunks)
  • apps/atrium-telegram/app/pages/startapp.vue (2 hunks)
  • apps/web-app/server/tasks/ai/daily-report.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/web-app/server/tasks/ai/daily-report.ts (2)
packages/database/src/repository/index.ts (1)
  • repository (63-63)
apps/web-app/server/services/telegram/atrium-bot.ts (1)
  • useAtriumBot (95-101)
⏰ 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 (4)
apps/atrium-telegram/app/components/StaffBlock.vue (2)

3-3: LGTM on tighter grid spacing.

The reduced inner gap and wrapping look fine and should fit more tiles per row.


29-31: Name line addition looks good.

Bold + clamp improves scannability without overflow.

apps/atrium-telegram/app/pages/startapp.vue (1)

2-2: Loader tweak is fine.

size-8 text-primary animate-spin reads well for a transient splash.

apps/web-app/server/tasks/ai/daily-report.ts (1)

67-70: Teaser generation looks good.

40-word intro + CTA is concise and should improve CTR while keeping the full text in Atrium.

Comment on lines +58 to 62
const flowItem = await repository.flow.createItem({
type: 'daily_task_report',
title: `Задачи ${date}`,
description: finalMessage,
})

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

Guard against missing flowItem.id to avoid sending broken links.

If createItem fails or returns no id, the URL becomes ...startapp=flowzzzzzundefined. Bail out early.

       const flowItem = await repository.flow.createItem({
         type: 'daily_task_report',
         title: `Задачи ${date}`,
         description: finalMessage,
       })
+
+      if (!flowItem?.id) {
+        logger.warn('daily-report: flow item was not created or has no id; skipping Telegram post')
+        return { result: true }
+      }
📝 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 flowItem = await repository.flow.createItem({
type: 'daily_task_report',
title: `Задачи ${date}`,
description: finalMessage,
})
const flowItem = await repository.flow.createItem({
type: 'daily_task_report',
title: `Задачи ${date}`,
description: finalMessage,
})
if (!flowItem?.id) {
logger.warn('daily-report: flow item was not created or has no id; skipping Telegram post')
return { result: true }
}
🤖 Prompt for AI Agents
In apps/web-app/server/tasks/ai/daily-report.ts around lines 58 to 62, the code
assumes repository.flow.createItem returns an object with id and will build a
URL using flowItem.id; add a guard to check that flowItem exists and has a
truthy id before proceeding to build or send any links — if missing, log an
error/warning and return early (or throw) to avoid producing a URL containing
"undefined". Ensure any callers handle this early exit and include a clear log
message with the failed response details for debugging.

Comment on lines +64 to +66
const separator = 'zzzzz'
const startAppData = `flow${separator}${flowItem?.id}`

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Encode and centralize startapp payload.

  • URL-encode the payload to be safe.
  • Reuse a shared TG_STARTAPP_SEPARATOR constant across server and client.
-      const separator = 'zzzzz'
-      const startAppData = `flow${separator}${flowItem?.id}`
+      const separator = 'zzzzz' // TODO: import from shared constants
+      const startAppData = `flow${separator}${flowItem.id}`
+      const startAppParam = encodeURIComponent(startAppData)

Verification helper:


🏁 Script executed:

#!/bin/bash
# Check all usages of the separator and startapp param construction.
rg -nP "zzzzz|startapp=" -C2

Length of output: 2436


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== apps/web-app/server/tasks/ai/daily-report.ts ==="
nl -ba apps/web-app/server/tasks/ai/daily-report.ts | sed -n '1,220p' || true

echo
echo "=== apps/web-app/server/api/beacon/epic/comment.post.ts ==="
nl -ba apps/web-app/server/api/beacon/epic/comment.post.ts | sed -n '1,220p' || true

echo
echo "=== apps/atrium-telegram/app/pages/startapp.vue ==="
nl -ba apps/atrium-telegram/app/pages/startapp.vue | sed -n '1,240p' || true

echo
echo "=== apps/storefront-telegram/app/pages/startapp.vue ==="
nl -ba apps/storefront-telegram/app/pages/startapp.vue | sed -n '1,240p' || true

Length of output: 389


Centralize TG_STARTAPP_SEPARATOR and URL‑encode startapp payload

Local 'zzzzz' separator found in:

  • apps/web-app/server/tasks/ai/daily-report.ts
  • apps/web-app/server/api/beacon/epic/comment.post.ts
  • apps/atrium-telegram/app/pages/startapp.vue
  • apps/storefront-telegram/app/pages/startapp.vue

Actions:

  • Export a single TG_STARTAPP_SEPARATOR from a shared module and import it in all server/client files (replace each local "zzzzz").
  • Encode the payload on the server: const startAppParam = encodeURIComponent(startAppData); use ?startapp=${startAppParam} in URLs.
  • Decode on the client before parsing: const startAppData = decodeURIComponent(tgWebAppStartParam as string || ''); then split by TG_STARTAPP_SEPARATOR.
  • Do not remove optional chaining (e.g., flowItem?.id) unless you verify the value is always present.
🤖 Prompt for AI Agents
In apps/web-app/server/tasks/ai/daily-report.ts around lines 64-66, replace the
local separator ('zzzzz') with a shared constant exported from a common module
(e.g., TG_STARTAPP_SEPARATOR) and import it here and in the other listed files;
when building the startapp payload, URL-encode it on the server (use
encodeURIComponent) and use ?startapp=<encoded> in generated URLs; on the client
decode with decodeURIComponent before parsing (then split by
TG_STARTAPP_SEPARATOR) and keep optional chaining (e.g., flowItem?.id) as-is
unless you can guarantee the value is present.

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