fix: remove manual project creation, smart sequence release, received-invoices schema fix

- Remove ProjectCreate page, POST /projects endpoint, and next-number endpoint
- Projects can only be created through orders (shared numbering sequence)
- Remove dead CreateProjectSchema and createProject service function
- Delete 'order' row from number_sequences (unused; code uses 'shared')
- Smart sequence release: decrement last_number only when deleting the highest number
- Fix received-invoices stats referencing non-existent is_deleted and amount_czk columns
- Update deploy instructions in CLAUDE.md (npm install, prisma migrate deploy)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
BOHA
2026-04-28 11:36:08 +02:00
parent 3481b97d47
commit 82919d39f6
12 changed files with 86 additions and 558 deletions

View File

@@ -1,9 +1,5 @@
import prisma from "../config/database";
import {
generateSharedNumber,
previewSharedNumber,
releaseSharedNumber,
} from "./numbering.service";
import { releaseSharedNumber } from "./numbering.service";
import { NasFileManager } from "./nas-file-manager";
const nasFileManager = new NasFileManager();
@@ -96,50 +92,6 @@ export async function getProject(id: number) {
};
}
import { isSharedNumberTaken } from "./numbering.service";
export async function createProject(body: Record<string, any>) {
const projectNumber =
body.project_number !== undefined && body.project_number !== null
? String(body.project_number)
: await generateSharedNumber();
if (body.project_number !== undefined && body.project_number !== null) {
const taken = await isSharedNumberTaken(String(body.project_number));
if (taken) {
return { error: "Číslo projektu je již použito", status: 400 };
}
}
const project = await prisma.projects.create({
data: {
project_number: projectNumber,
name: body.name ? String(body.name) : null,
customer_id: body.customer_id != null ? Number(body.customer_id) : null,
responsible_user_id:
body.responsible_user_id != null
? Number(body.responsible_user_id)
: null,
quotation_id:
body.quotation_id != null ? Number(body.quotation_id) : null,
order_id: body.order_id != null ? Number(body.order_id) : null,
status: body.status ? String(body.status) : "aktivni",
start_date: body.start_date ? new Date(String(body.start_date)) : null,
end_date: body.end_date ? new Date(String(body.end_date)) : null,
notes: body.notes ? String(body.notes) : null,
},
});
if (project.project_number && nasFileManager.isConfigured()) {
nasFileManager.createProjectFolder(
project.project_number,
project.name || "",
);
}
return project;
}
export async function updateProject(id: number, body: Record<string, any>) {
const existing = await prisma.projects.findUnique({ where: { id } });
if (!existing) return null;
@@ -206,7 +158,7 @@ export async function deleteProject(id: number, deleteFiles: boolean = false) {
const year = existing.created_at
? new Date(existing.created_at).getFullYear()
: new Date().getFullYear();
await releaseSharedNumber(year);
await releaseSharedNumber(year, existing.project_number ?? undefined);
return existing;
}
@@ -248,7 +200,3 @@ export async function deleteProjectNote(projectId: number, noteId: number) {
await prisma.project_notes.delete({ where: { id: noteId } });
return note;
}
export async function getNextProjectNumber() {
return previewSharedNumber();
}