-
Notifications
You must be signed in to change notification settings - Fork 0
Complete Backend Prototype #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…no more than 12 hrs ago
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements a complete backend prototype for a QueueBot application using Fastify, Prisma, and TypeScript. It includes JWT-based authentication, admin management, and queue operations with Telegram Mini App integration.
Changes:
- Migrated from CommonJS to ES modules with updated TypeScript configuration
- Implemented JWT authentication with Telegram Mini App validation
- Created database schema with Prisma (Admin, Queue, QueueConfig, AdminRequester models)
- Built REST API with public and private routes for queue and admin management
Reviewed changes
Copilot reviewed 22 out of 23 changed files in this pull request and generated 15 comments.
Show a summary per file
| File | Description |
|---|---|
| backend/tsconfig.json | Updated to ESNext/NodeNext with stricter type checking |
| backend/package.json | Added dependencies (jose, fastify plugins, pg adapter) and switched to ESM |
| backend/src/server.ts | Main server setup with CORS, JWT auth, and route autoloading |
| backend/src/types.ts | Type definitions for Fastify extensions and Telegram data |
| backend/src/shared.ts | Admin authorization middleware |
| backend/src/prismaPlugin.ts | Prisma client plugin with PostgreSQL adapter |
| backend/src/queueConfigPlugin.ts | Queue configuration caching plugin |
| backend/src/routes/public/auth/index.ts | Telegram Mini App authentication endpoint |
| backend/src/routes/private/queue/*.ts | Queue management endpoints (status, config, next, entries) |
| backend/src/routes/private/admins/*.ts | Admin and admin request management endpoints |
| backend/prisma/schema.prisma | Database schema with 4 models |
| backend/README.md | Comprehensive API documentation |
Files not reviewed (1)
- backend/package-lock.json: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let config = await fastify.prisma.queueConfig.findFirst().then((queueConfig) => queueConfig); | ||
|
|
||
| if (config === null) { | ||
| reply.code(500); | ||
| throw new Error("No queue configured"); | ||
| } | ||
|
|
||
| config.isOpen = request.query.open; |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing input validation: The 'open' query parameter is parsed from stringbool but there's no validation that the config exists before trying to update it. The check happens after attempting to set the property on a potentially null object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no issue here
| // hit Telegram API to send user message | ||
| fetch(`https://api.telegram.org/bot${BOT_TOKEN}/test/sendMessage?${queryString}`, { | ||
| method: 'POST', | ||
| }) |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing error handling for the Telegram API fetch request. If the request fails, there's no catch block or error handling, which could lead to unhandled promise rejections.
| }) | |
| }).catch((error) => { | |
| fastify.log.error({ err: error }, 'Failed to send Telegram notification'); | |
| }); |
| import type {FastifyPluginAsyncZod} from "fastify-type-provider-zod"; | ||
| import {isAdmin} from "../../../shared.js"; | ||
|
|
||
| const BOT_TOKEN = process.env.BOT_TOKEN; |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The BOT_TOKEN is accessed without the non-null assertion operator, unlike other files, and could be undefined. Add validation or use the non-null assertion consistently.
| const BOT_TOKEN = process.env.BOT_TOKEN; | |
| const BOT_TOKEN = process.env.BOT_TOKEN!; |
backend/src/prismaPlugin.ts
Outdated
| const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL }) | ||
|
|
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The database URL environment variable is accessed without validation. If DATABASE_URL is undefined, the PrismaClient will fail to initialize. Add validation at startup.
| const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL }) | |
| const databaseUrl = process.env.DATABASE_URL | |
| if (!databaseUrl) { | |
| throw new Error('DATABASE_URL environment variable is not set. Please configure it before starting the server.') | |
| } | |
| const adapter = new PrismaPg({ connectionString: databaseUrl }) |
| fastify.prisma.admin.count().then((count) => console.log(count)); | ||
|
|
||
| }); | ||
|
|
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The public index route logs admin count to console but doesn't return any response. This will cause Fastify to timeout or send an empty response. Either remove this TODO endpoint or add a proper reply.
| fastify.prisma.admin.count().then((count) => console.log(count)); | |
| }); | |
| const count = await fastify.prisma.admin.count(); | |
| console.log(count); | |
| return reply.send({ adminCount: count }); | |
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will remove this example endpoint
| reply.code(500); | ||
| throw new Error(e.message); |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error from catch block is being re-thrown, but the reply code has already been set. This will cause Fastify to log a warning about attempting to send headers after they've been sent. The catch block should return or handle the error properly without throwing.
| reply.code(500); | |
| throw new Error(e.message); | |
| // Handle internal errors without re-throwing after setting the reply code | |
| if (request.log && typeof request.log.error === "function") { | |
| request.log.error(e, "Error while checking admin privileges"); | |
| } | |
| if (!reply.sent) { | |
| reply.code(500).send({ error: e.message }); | |
| } |
| const queryString = new URLSearchParams( | ||
| {'chat_id': allEntries[i]!.telegram_id, 'text': message, 'parse_mode': 'Markdown'}).toString(); | ||
| // hit Telegram API to send user message | ||
| fetch(`https://api.telegram.org/bot${BOT_TOKEN}/test/sendMessage?${queryString}`, { |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect Telegram API endpoint: The URL includes "/test/" which is not a valid part of the Telegram Bot API path. The correct endpoint should be "https://api.telegram.org/bot{BOT_TOKEN}/sendMessage" without the "test" segment.
| fetch(`https://api.telegram.org/bot${BOT_TOKEN}/test/sendMessage?${queryString}`, { | |
| fetch(`https://api.telegram.org/bot${BOT_TOKEN}/sendMessage?${queryString}`, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
URL is correct, "/test/" points to Telegram API for staging environment. Should add check to switch between staging and production based on Node Env
| @@ -0,0 +1,67 @@ | |||
| import {z} from 'zod'; | |||
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused import z.
| import {z} from 'zod'; |
| @@ -0,0 +1,67 @@ | |||
| import {z} from 'zod'; | |||
| import type { FastifyPluginAsyncZod } from "fastify-type-provider-zod"; | |||
| import { isAdmin } from "../../../../../shared.js"; | |||
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused import isAdmin.
| import { isAdmin } from "../../../../../shared.js"; |
| fastify.log.error(err) | ||
| process.exit(1) | ||
| } | ||
| } |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid automated semicolon insertion (91% of all statements in the enclosing script have an explicit semicolon).
Implemented all backend API per previously discussed specifications.