changemaker.lite/api/src/modules/pages/blocks.service.ts
bunker-admin a77306fac2 Initial v2 commit: complete rebuild with unified API + React admin
Phase 1-14 complete:
- Unified Express.js API (TypeScript, Prisma ORM, PostgreSQL 16)
- React Admin GUI (Vite + Ant Design + Zustand)
- JWT auth with refresh tokens
- Influence: Campaigns, Representatives, Responses, Email Queue
- Map: Locations, Cuts, Shifts, Canvassing System
- NAR data import infrastructure (2025 format)
- Listmonk newsletter integration
- Landing page builder (GrapesJS)
- MkDocs + Code Server integration
- Volunteer portal with GPS tracking
- Monitoring stack (Prometheus, Grafana, Alertmanager)
- Pangolin tunnel integration

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-11 10:05:04 -07:00

89 lines
2.3 KiB
TypeScript

import { Prisma } from '@prisma/client';
import { prisma } from '../../config/database';
import { AppError } from '../../middleware/error-handler';
import type { CreatePageBlockInput, UpdatePageBlockInput, ListPageBlocksInput } from './pages.schemas';
const blockSelect = {
id: true,
type: true,
label: true,
schema: true,
defaults: true,
thumbnail: true,
category: true,
sortOrder: true,
createdAt: true,
updatedAt: true,
} satisfies Prisma.PageBlockSelect;
export const blocksService = {
async findAll(filters: ListPageBlocksInput) {
const where: Prisma.PageBlockWhereInput = {};
if (filters.category) {
where.category = filters.category;
}
return prisma.pageBlock.findMany({
where,
select: blockSelect,
orderBy: { sortOrder: 'asc' },
});
},
async findById(id: string) {
const block = await prisma.pageBlock.findUnique({
where: { id },
select: blockSelect,
});
if (!block) {
throw new AppError(404, 'Page block not found', 'BLOCK_NOT_FOUND');
}
return block;
},
async create(data: CreatePageBlockInput) {
return prisma.pageBlock.create({
data: {
...data,
schema: data.schema as unknown as Prisma.InputJsonValue,
defaults: data.defaults as unknown as Prisma.InputJsonValue,
},
select: blockSelect,
});
},
async update(id: string, data: UpdatePageBlockInput) {
const existing = await prisma.pageBlock.findUnique({ where: { id } });
if (!existing) {
throw new AppError(404, 'Page block not found', 'BLOCK_NOT_FOUND');
}
const updateData: Prisma.PageBlockUncheckedUpdateInput = { ...data };
if (data.schema !== undefined) {
updateData.schema = data.schema as unknown as Prisma.InputJsonValue;
}
if (data.defaults !== undefined) {
updateData.defaults = data.defaults as unknown as Prisma.InputJsonValue;
}
return prisma.pageBlock.update({
where: { id },
data: updateData,
select: blockSelect,
});
},
async delete(id: string) {
const existing = await prisma.pageBlock.findUnique({ where: { id } });
if (!existing) {
throw new AppError(404, 'Page block not found', 'BLOCK_NOT_FOUND');
}
await prisma.pageBlock.delete({ where: { id } });
},
};