Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 1 addition & 13 deletions apps/atrium-telegram/server/api/auth/me.get.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,5 @@
import { repository } from '@roll-stack/database'

export default defineEventHandler(async (event) => {
try {
const user = event.context.user
if (!user) {
throw createError({
statusCode: 401,
message: 'Not logged in',
})
}

return repository.user.find(user.id)
} catch (error) {
throw errorResolver(error)
}
return repository.user.find(event.context.user.id)
})
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,6 @@ export default defineEventHandler(async (event) => {
})
}

const user = event.context.user
if (!user) {
throw createError({
statusCode: 401,
message: 'Not logged in',
})
}

// Guard: not this user
const commentInDB = await repository.epic.findComment(commentId)
if (!commentInDB) {
Expand All @@ -26,7 +18,7 @@ export default defineEventHandler(async (event) => {
message: 'Not found',
})
}
if (commentInDB.userId !== user.id) {
if (commentInDB.userId !== event.context.user.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.

🛠️ Refactor suggestion

Unsafe access to event.context.user.id — guard against missing user.

Align with middleware assumptions but fail safe locally to avoid runtime TypeError.

-    if (commentInDB.userId !== event.context.user.id) {
+    if (!event.context.user || commentInDB.userId !== event.context.user.id) {
📝 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
if (commentInDB.userId !== event.context.user.id) {
if (!event.context.user || commentInDB.userId !== event.context.user.id) {
// existing logic…
}
🤖 Prompt for AI Agents
In apps/atrium-telegram/server/api/epic/comment/id/[commentId]/index.delete.ts
around line 21, the code directly accesses event.context.user.id which can be
undefined and cause a TypeError; add a defensive guard that verifies
event.context and event.context.user exist and that user.id is present before
comparing to commentInDB.userId, and if the user is missing return/throw an
unauthorized response (HTTP 401) or appropriate error; update the comparison to
run only after this check so the handler fails safely when no authenticated user
is present.

throw createError({
statusCode: 400,
message: 'Not your comment',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,6 @@ export default defineEventHandler(async (event) => {
})
}

const user = event.context.user
if (!user) {
throw createError({
statusCode: 401,
message: 'Not logged in',
})
}

const body = await readBody(event)
const data = createEpicCommentSchema(body)
if (data instanceof type.errors) {
Expand All @@ -28,7 +20,7 @@ export default defineEventHandler(async (event) => {

const comment = await repository.epic.createComment({
...data,
userId: user.id,
userId: event.context.user.id,
epicId,
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,6 @@ export default defineEventHandler(async (event) => {
})
}

const user = event.context.user
if (!user) {
throw createError({
statusCode: 401,
message: 'Not logged in',
})
}

const body = await readBody(event)
const data = updateEpicSchema(body)
if (data instanceof type.errors) {
Expand Down
18 changes: 5 additions & 13 deletions apps/atrium-telegram/server/api/epic/index.post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,9 @@ export default defineEventHandler(async (event) => {
throw data
}

const user = event.context.user
if (!user) {
throw createError({
statusCode: 401,
message: 'Not logged in',
})
}

const epic = await repository.epic.create({
...data,
userId: user.id,
userId: event.context.user.id,
})
if (!epic) {
throw createError({
Expand All @@ -30,17 +22,17 @@ export default defineEventHandler(async (event) => {
}

// Notify all staff
if (user.type === 'staff') {
if (event.context.user.type === 'staff') {
const users = await repository.user.list()
const allStaffExceptUser = users.filter((u) => u.type === 'staff' && u.id !== user.id)
const allStaffExceptUser = users.filter((u) => u.type === 'staff' && u.id !== event.context.user.id)

for (const staff of allStaffExceptUser) {
await repository.notification.create({
authorId: user.id,
authorId: event.context.user.id,
userId: staff.id,
epicId: epic.id,
type: 'epic_created',
title: `${suffixByGender(['Создал', 'Создала'], user.gender)} эпик «${epic.title}»`,
title: `${suffixByGender(['Создал', 'Создала'], event.context.user.gender)} эпик «${epic.title}»`,
description: epic.description ? epic.description : 'Без описания',
})
}
Expand Down
10 changes: 1 addition & 9 deletions apps/atrium-telegram/server/api/epic/list.get.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
import { repository } from '@roll-stack/database'

export default defineEventHandler(async (event) => {
const user = event.context.user
if (!user) {
throw createError({
statusCode: 401,
message: 'Not logged in',
})
}

export default defineEventHandler(async () => {
return repository.epic.list()
})
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,6 @@ import { repository } from '@roll-stack/database'

export default defineEventHandler(async (event) => {
try {
const user = event.context.user
if (!user) {
throw createError({
statusCode: 401,
message: 'Not logged in',
})
}

const notificationId = getRouterParam(event, 'notificationId')
if (!notificationId) {
throw createError({
Expand Down
14 changes: 1 addition & 13 deletions apps/atrium-telegram/server/api/notification/my.get.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,5 @@
import { repository } from '@roll-stack/database'

export default defineEventHandler(async (event) => {
try {
const user = event.context.user
if (!user) {
throw createError({
statusCode: 401,
message: 'Not logged in',
})
}

return repository.notification.listByUser(user.id)
} catch (error) {
throw errorResolver(error)
}
return repository.notification.listByUser(event.context.user.id)
})
Comment on lines 3 to 5
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

Potential NPE on event.context.user and inconsistent error handling.

Ensure middleware guards this route; consider consistent try/catch with errorResolver like other handlers.

Run to confirm middleware coverage and existing error handling conventions:


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n 'errorResolver\(' apps/atrium-telegram/server/api | head -n 50
fd -a '01.auth.ts' apps | xargs -I{} sed -n '1,220p' "{}" | rg -n 'event\.context\.user'

Length of output: 1665


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate and display auth middleware file
auth_file=$(fd '01.auth.ts' apps/atrium-telegram)
echo "Auth middleware file: $auth_file"
sed -n '1,200p' "$auth_file"

# Locate and display Nuxt config file
nuxt_cfg=$(fd 'nuxt.config.ts' apps/atrium-telegram)
echo "Nuxt config file: $nuxt_cfg"
sed -n '1,200p' "$nuxt_cfg"

# Search for middleware registration in config
rg -n 'middleware' -C 3 "$nuxt_cfg"

# List server and middleware directories
find apps/atrium-telegram/server -maxdepth 2 -type d

# Confirm usage of event.context.user across codebase
rg -n 'event\.context\.user' -C 2 apps/atrium-telegram

Length of output: 3459


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Display the handler implementation
sed -n '1,200p' apps/atrium-telegram/server/api/notification/my.get.ts

# Check for existing error handling patterns
rg -n 'try' -C 3 apps/atrium-telegram/server/api/notification/my.get.ts || true
rg -n 'errorResolver' -C 3 apps/atrium-telegram/server/api/notification/my.get.ts || true

Length of output: 432


Add try/catch with errorResolver
Wrap the repository call in a try { … } catch (error) { throw errorResolver(error) } to align with other handlers; the global auth middleware (server/middleware/01.auth.ts) already guarantees event.context.user is set for /api/** routes. [apps/atrium-telegram/server/api/notification/my.get.ts]

🤖 Prompt for AI Agents
In apps/atrium-telegram/server/api/notification/my.get.ts around lines 3 to 5,
the repository call is unprotected and should be wrapped in a try/catch that
uses errorResolver; update the handler to call
repository.notification.listByUser(event.context.user.id) inside try and in
catch throw errorResolver(error) so errors are normalized like other handlers
(no need to re-check event.context.user because auth middleware guarantees it).

Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,6 @@ export default defineEventHandler(async (event) => {
throw data
}

const user = event.context.user
if (!user) {
throw createError({
statusCode: 401,
message: 'Not logged in',
})
}

// Guards:
// If task not exist
// If performer is not user
Expand All @@ -38,7 +30,7 @@ export default defineEventHandler(async (event) => {
message: 'Task not found',
})
}
if (!!task.performerId && task.performerId !== user.id) {
if (!!task.performerId && task.performerId !== event.context.user.id) {
throw createError({
statusCode: 403,
message: 'You are not the performer of this task',
Expand All @@ -57,8 +49,8 @@ export default defineEventHandler(async (event) => {
}

// Clear focus if needed
if (user.focusedTaskId === taskId) {
await repository.user.update(user.id, {
if (event.context.user.focusedTaskId === taskId) {
await repository.user.update(event.context.user.id, {
focusedTaskId: null,
})
}
Expand All @@ -75,7 +67,7 @@ export default defineEventHandler(async (event) => {
if (list.chat) {
const bot = await repository.chat.findNotificationBot(list.chat.id)
if (bot) {
const text = prepareBotMessage(user, updatedTask)
const text = prepareBotMessage(event.context.user, updatedTask)

// Send message as bot
await repository.chat.createMessage({
Expand All @@ -87,18 +79,18 @@ export default defineEventHandler(async (event) => {
}

// Notify all staff
if (user.type === 'staff') {
if (event.context.user.type === 'staff') {
const users = await repository.user.list()
const allStaffExceptUser = users.filter((u) => u.type === 'staff' && u.id !== user.id)
const allStaffExceptUser = users.filter((u) => u.type === 'staff' && u.id !== event.context.user.id)

for (const staff of allStaffExceptUser) {
if (staff.notifications.includes('task_completed_atrium')) {
await repository.notification.create({
authorId: user.id,
authorId: event.context.user.id,
userId: staff.id,
taskId: updatedTask.id,
type: 'task_completed',
title: `${suffixByGender(['Завершил', 'Завершила'], user.gender)} задачу «${updatedTask.name}»`,
title: `${suffixByGender(['Завершил', 'Завершила'], event.context.user.gender)} задачу «${updatedTask.name}»`,
description: updatedTask.report ? updatedTask.report : 'Без отчета',
})
Comment on lines +93 to 95
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

Missing import for suffixByGender → runtime/TS error

suffixByGender is used but not imported.

-import { getLocalizedResolution } from '#shared/utils/helpers'
+import { getLocalizedResolution, suffixByGender } from '#shared/utils/helpers'

Also applies to: 106-117

🤖 Prompt for AI Agents
In apps/atrium-telegram/server/api/task/id/[taskId]/complete.post.ts around
lines 93-95 (also where similar usage occurs at 106-117), suffixByGender is
referenced but not imported causing a runtime/TypeScript error; fix by adding
the appropriate named import for suffixByGender from the module where it’s
defined (for example add: import { suffixByGender } from
'<correct-module-path>') at the top of the file so both occurrences resolve at
runtime.

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,6 @@ export default defineEventHandler(async (event) => {
})
}

const user = event.context.user
if (!user) {
throw createError({
statusCode: 401,
message: 'Not logged in',
})
}

// Guards:
// If task not exist
// If performer is not user
Expand All @@ -28,14 +20,14 @@ export default defineEventHandler(async (event) => {
message: 'Task not found',
})
}
if (task.performerId !== user.id) {
if (task.performerId !== event.context.user.id) {
throw createError({
statusCode: 403,
message: 'You are not the performer of this task',
})
}

await repository.user.update(user.id, {
await repository.user.update(event.context.user.id, {
focusedTaskId: null,
})

Expand Down
14 changes: 3 additions & 11 deletions apps/atrium-telegram/server/api/task/id/[taskId]/focus.post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,6 @@ export default defineEventHandler(async (event) => {
})
}

const user = event.context.user
if (!user) {
throw createError({
statusCode: 401,
message: 'Not logged in',
})
}

// Guards:
// If task not exist
// If performer is not user
Expand All @@ -29,20 +21,20 @@ export default defineEventHandler(async (event) => {
message: 'Task not found',
})
}
if (task.performerId !== user.id) {
if (task.performerId !== event.context.user.id) {
throw createError({
statusCode: 403,
message: 'You are not the performer of this task',
})
}
if (user.focusedTaskId === taskId) {
if (event.context.user.focusedTaskId === taskId) {
throw createError({
statusCode: 400,
message: 'Task already focused',
})
}

await repository.user.update(user.id, {
await repository.user.update(event.context.user.id, {
focusedTaskId: taskId,
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,6 @@ export default defineEventHandler(async (event) => {
})
}

const user = event.context.user
if (!user) {
throw createError({
statusCode: 401,
message: 'Not logged in',
})
}

await repository.task.delete(taskId)

return { ok: true }
Expand Down
12 changes: 2 additions & 10 deletions apps/atrium-telegram/server/api/task/id/[taskId]/index.patch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,6 @@ export default defineEventHandler(async (event) => {
throw data
}

const user = event.context.user
if (!user) {
throw createError({
statusCode: 401,
message: 'Not logged in',
})
}

const task = await repository.task.find(taskId)
if (!task) {
throw createError({
Expand All @@ -44,7 +36,7 @@ export default defineEventHandler(async (event) => {
})
}

const canEdit = list.chat?.members.some((member) => member.userId === user.id)
const canEdit = list.chat?.members.some((member) => member.userId === event.context.user.id)

// Guard: if don't have access
if (!canEdit) {
Expand All @@ -68,7 +60,7 @@ export default defineEventHandler(async (event) => {
if (list.chat) {
const bot = await repository.chat.findNotificationBot(list.chat.id)
if (bot) {
const text = prepareBotMessage(user, task, updatedTask, updatedPerformer)
const text = prepareBotMessage(event.context.user, task, updatedTask, updatedPerformer)

// Send message as bot
await repository.chat.createMessage({
Comment on lines 61 to 66
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

prepareBotMessage likely needs a fully-loaded User

event.context.user must have name, surname, and gender. If middleware only attaches minimal claims, bot text will degrade (e.g., undefined undefined). Prefer fetching the author or enriching middleware.

-        const text = prepareBotMessage(event.context.user, task, updatedTask, updatedPerformer)
+        const author = await repository.user.find(event.context.user.id)
+        if (!author) {
+          throw createError({ statusCode: 500, message: 'Author not found' })
+        }
+        const text = prepareBotMessage(author, task, updatedTask, updatedPerformer)
📝 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 bot = await repository.chat.findNotificationBot(list.chat.id)
if (bot) {
const text = prepareBotMessage(user, task, updatedTask, updatedPerformer)
const text = prepareBotMessage(event.context.user, task, updatedTask, updatedPerformer)
// Send message as bot
await repository.chat.createMessage({
const bot = await repository.chat.findNotificationBot(list.chat.id)
if (bot) {
// Ensure we have a fully-loaded author for bot message formatting
const author = await repository.user.find(event.context.user.id)
if (!author) {
throw createError({ statusCode: 500, message: 'Author not found' })
}
const text = prepareBotMessage(author, task, updatedTask, updatedPerformer)
// Send message as bot
await repository.chat.createMessage({

Expand Down
10 changes: 1 addition & 9 deletions apps/atrium-telegram/server/api/task/index.post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,6 @@ export default defineEventHandler(async (event) => {
throw data
}

const user = event.context.user
if (!user) {
throw createError({
statusCode: 401,
message: 'Not logged in',
})
}

const task = await repository.task.create({
name: data.name,
description: data.description,
Expand All @@ -45,7 +37,7 @@ export default defineEventHandler(async (event) => {
if (list.chat) {
const bot = await repository.chat.findNotificationBot(list.chat.id)
if (bot) {
const text = `${user.name} ${user.surname} ${suffixByGender(['создал', 'создала'], user.gender)} задачу «${task.name}»`
const text = `${event.context.user.name} ${event.context.user.surname} ${suffixByGender(['создал', 'создала'], event.context.user.gender)} задачу «${task.name}»`

// Send message as bot
await repository.chat.createMessage({
Expand Down
Loading