diff --git a/package.json b/package.json index 12a94ae..2d1b474 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "russcult_server", - "version": "1.0.6", + "version": "1.0.7", "main": "index.js", "scripts": { "build": "tsc", diff --git a/prisma/migrations/20251112161514_add_announcement_table/migration.sql b/prisma/migrations/20251112161514_add_announcement_table/migration.sql new file mode 100644 index 0000000..113fc1d --- /dev/null +++ b/prisma/migrations/20251112161514_add_announcement_table/migration.sql @@ -0,0 +1,10 @@ +-- CreateTable +CREATE TABLE "Announcement" ( + "id" TEXT NOT NULL, + "message" TEXT NOT NULL, + "isActive" BOOLEAN NOT NULL DEFAULT true, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "Announcement_pkey" PRIMARY KEY ("id") +); diff --git a/prisma/migrations/migration_lock.toml b/prisma/migrations/migration_lock.toml index 648c57f..044d57c 100644 --- a/prisma/migrations/migration_lock.toml +++ b/prisma/migrations/migration_lock.toml @@ -1,3 +1,3 @@ # Please do not edit this file manually # It should be added in your version-control system (e.g., Git) -provider = "postgresql" \ No newline at end of file +provider = "postgresql" diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 6e52aca..90c8ad0 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -102,3 +102,11 @@ model UserReaction { @@unique([userId, articleId]) } + +model Announcement { + id String @id @default(uuid()) + message String + isActive Boolean @default(true) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} diff --git a/src/routes/announcements/controllers/announcements.ts b/src/routes/announcements/controllers/announcements.ts new file mode 100644 index 0000000..5330358 --- /dev/null +++ b/src/routes/announcements/controllers/announcements.ts @@ -0,0 +1,88 @@ +import { Request, Response } from 'express'; +import { prisma } from '../../../lib/prisma'; + +export async function getActiveAnnouncement(req: Request, res: Response) { + try { + const announcement = await prisma.announcement.findFirst({ + where: { isActive: true }, + orderBy: { createdAt: 'desc' }, + select: { + id: true, + message: true + } + }); + + if (!announcement) { + return res.status(204).send(); + } + + res.json(announcement); + } catch (error) { + res.status(500).json({ error: 'Server error' }); + } +} + +export async function createAnnouncement(req: Request, res: Response) { + try { + const { message } = req.body; + + if (!message || typeof message !== 'string' || message.trim().length === 0) { + return res.status(400).json({ error: 'Message is required' }); + } + + const announcement = await prisma.announcement.create({ + data: { + message: message.trim() + } + }); + + res.status(201).json(announcement); + } catch (error) { + res.status(500).json({ error: 'Server error' }); + } +} + +export async function updateAnnouncement(req: Request, res: Response) { + try { + const { id } = req.params; + const { message, isActive } = req.body; + + const announcement = await prisma.announcement.update({ + where: { id }, + data: { + ...(message && { message: message.trim() }), + ...(typeof isActive === 'boolean' && { isActive }) + } + }); + + res.json(announcement); + } catch (error) { + res.status(500).json({ error: 'Server error' }); + } +} + +export async function deleteAnnouncement(req: Request, res: Response) { + try { + const { id } = req.params; + + await prisma.announcement.delete({ + where: { id } + }); + + res.status(204).send(); + } catch (error) { + res.status(500).json({ error: 'Server error' }); + } +} + +export async function getAllAnnouncements(req: Request, res: Response) { + try { + const announcements = await prisma.announcement.findMany({ + orderBy: { createdAt: 'desc' } + }); + + res.json(announcements); + } catch (error) { + res.status(500).json({ error: 'Server error' }); + } +} diff --git a/src/routes/announcements/index.ts b/src/routes/announcements/index.ts new file mode 100644 index 0000000..dc893aa --- /dev/null +++ b/src/routes/announcements/index.ts @@ -0,0 +1,20 @@ +import { Router } from 'express'; +import { auth } from '../../middleware/auth'; +import { + getActiveAnnouncement, + createAnnouncement, + updateAnnouncement, + deleteAnnouncement, + getAllAnnouncements +} from './controllers/announcements'; + +const router = Router(); + +router.get('/active', getActiveAnnouncement); + +router.get('/', auth, getAllAnnouncements); +router.post('/', auth, createAnnouncement); +router.put('/:id', auth, updateAnnouncement); +router.delete('/:id', auth, deleteAnnouncement); + +export default router; diff --git a/src/server.ts b/src/server.ts index 588d5a3..a6a2704 100644 --- a/src/server.ts +++ b/src/server.ts @@ -12,6 +12,7 @@ import galleryRoutes from './routes/gallery/index'; import imagesRoutes from './routes/images/index'; import authorRoutes from './routes/authors/index'; import otherRoutes from './routes/other/index'; +import announcementRoutes from './routes/announcements/index'; const app = express(); @@ -40,6 +41,7 @@ app.use('/api/articles', articleRoutes); app.use('/api/gallery', galleryRoutes); app.use('/api/images', imagesRoutes); app.use('/api/other', otherRoutes); +app.use('/api/announcements', announcementRoutes); // Запуск сервера app.listen(PORT, () => {