Files
url_tracker_tool/apps/api/dist/routes/projects.routes.js
Andrei f797f9b07c feat: Simplify home page and remove tracking form
- Remove complex tracking form from home page
- Replace with clean 'Analyze URL Redirects' call-to-action button
- Remove announcement badge '🚀 URL Tracker Tool V2 - Now Available'
- Clean up unused imports and form-related code
- Direct users to dedicated /track page for full functionality
- Improve user experience with cleaner, more focused home page

Changes:
- Simplified HomePage component with single CTA button
- Removed form validation, mutation handling, and result display
- Maintained all tracking functionality on /track page
- Professional appearance without promotional clutter
2025-08-23 19:07:02 +00:00

373 lines
13 KiB
JavaScript

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = __importDefault(require("express"));
const zod_1 = require("zod");
const auth_middleware_1 = require("../middleware/auth.middleware");
const client_1 = require("@prisma/client");
const logger_1 = require("../lib/logger");
const router = express_1.default.Router();
const prisma = new client_1.PrismaClient();
const createProjectSchema = zod_1.z.object({
name: zod_1.z.string().min(1, 'Project name is required').max(100, 'Project name too long'),
description: zod_1.z.string().optional(),
settings: zod_1.z.object({
defaultMethod: zod_1.z.enum(['GET', 'POST', 'HEAD']).default('GET'),
defaultTimeout: zod_1.z.number().min(1000).max(30000).default(15000),
defaultMaxHops: zod_1.z.number().min(1).max(20).default(10),
enableSSLAnalysis: zod_1.z.boolean().default(true),
enableSEOAnalysis: zod_1.z.boolean().default(true),
enableSecurityAnalysis: zod_1.z.boolean().default(true),
}).optional(),
});
const updateProjectSchema = zod_1.z.object({
name: zod_1.z.string().min(1).max(100).optional(),
description: zod_1.z.string().optional(),
settings: zod_1.z.object({
defaultMethod: zod_1.z.enum(['GET', 'POST', 'HEAD']).optional(),
defaultTimeout: zod_1.z.number().min(1000).max(30000).optional(),
defaultMaxHops: zod_1.z.number().min(1).max(20).optional(),
enableSSLAnalysis: zod_1.z.boolean().optional(),
enableSEOAnalysis: zod_1.z.boolean().optional(),
enableSecurityAnalysis: zod_1.z.boolean().optional(),
}).optional(),
});
const projectParamsSchema = zod_1.z.object({
projectId: zod_1.z.string().min(1),
});
router.get('/', auth_middleware_1.requireAuth, async (req, res) => {
try {
const user = req.user;
const orgId = user.memberships[0]?.orgId;
if (!orgId) {
return res.status(404).json({
success: false,
error: 'No organization found',
message: 'User must belong to an organization to access projects'
});
}
const projects = await prisma.project.findMany({
where: {
orgId: orgId,
},
include: {
_count: {
select: {
checks: true,
},
},
},
orderBy: {
createdAt: 'desc',
},
});
res.json({
success: true,
data: {
projects: projects.map(project => ({
id: project.id,
name: project.name,
description: project.settingsJson?.description || null,
settings: project.settingsJson,
trackingCount: project._count.checks,
createdAt: project.createdAt,
})),
},
});
}
catch (error) {
logger_1.logger.error('Failed to get projects:', error);
res.status(500).json({
success: false,
error: 'Failed to get projects',
message: error instanceof Error ? error.message : 'Unknown error',
});
}
});
router.post('/', auth_middleware_1.requireAuth, async (req, res) => {
try {
const user = req.user;
const orgId = user.memberships[0]?.orgId;
if (!orgId) {
return res.status(404).json({
success: false,
error: 'No organization found',
message: 'User must belong to an organization to create projects'
});
}
const validatedData = createProjectSchema.parse(req.body);
const project = await prisma.project.create({
data: {
name: validatedData.name,
orgId: orgId,
settingsJson: {
description: validatedData.description || '',
...validatedData.settings,
},
},
});
logger_1.logger.info(`Project created: ${project.id}`, {
userId: user.id,
orgId,
projectName: project.name,
});
res.status(201).json({
success: true,
data: {
project: {
id: project.id,
name: project.name,
description: validatedData.description || null,
settings: project.settingsJson,
trackingCount: 0,
createdAt: project.createdAt,
},
},
message: 'Project created successfully',
});
}
catch (error) {
logger_1.logger.error('Failed to create project:', error);
if (error instanceof zod_1.z.ZodError) {
return res.status(400).json({
success: false,
error: 'Validation failed',
details: error.errors,
});
}
res.status(500).json({
success: false,
error: 'Failed to create project',
message: error instanceof Error ? error.message : 'Unknown error',
});
}
});
router.get('/:projectId', auth_middleware_1.requireAuth, async (req, res) => {
try {
const user = req.user;
const { projectId } = projectParamsSchema.parse(req.params);
const orgId = user.memberships[0]?.orgId;
if (!orgId) {
return res.status(404).json({
success: false,
error: 'No organization found',
});
}
const project = await prisma.project.findFirst({
where: {
id: projectId,
orgId: orgId,
},
include: {
_count: {
select: {
checks: true,
},
},
checks: {
take: 10,
orderBy: {
startedAt: 'desc',
},
include: {
hops: {
select: {
url: true,
statusCode: true,
redirectType: true,
},
},
},
},
},
});
if (!project) {
return res.status(404).json({
success: false,
error: 'Project not found',
message: 'Project does not exist or you do not have access to it',
});
}
res.json({
success: true,
data: {
project: {
id: project.id,
name: project.name,
description: project.settingsJson?.description || null,
settings: project.settingsJson,
trackingCount: project._count.checks,
recentChecks: project.checks.map(check => ({
id: check.id,
inputUrl: check.inputUrl,
finalUrl: check.finalUrl,
status: check.status,
startedAt: check.startedAt,
hopCount: check.hops.length,
})),
createdAt: project.createdAt,
},
},
});
}
catch (error) {
logger_1.logger.error('Failed to get project:', error);
if (error instanceof zod_1.z.ZodError) {
return res.status(400).json({
success: false,
error: 'Invalid project ID',
});
}
res.status(500).json({
success: false,
error: 'Failed to get project',
message: error instanceof Error ? error.message : 'Unknown error',
});
}
});
router.put('/:projectId', auth_middleware_1.requireAuth, async (req, res) => {
try {
const user = req.user;
const { projectId } = projectParamsSchema.parse(req.params);
const orgId = user.memberships[0]?.orgId;
if (!orgId) {
return res.status(404).json({
success: false,
error: 'No organization found',
});
}
const validatedData = updateProjectSchema.parse(req.body);
const existingProject = await prisma.project.findFirst({
where: {
id: projectId,
orgId: orgId,
},
});
if (!existingProject) {
return res.status(404).json({
success: false,
error: 'Project not found',
message: 'Project does not exist or you do not have access to it',
});
}
const currentSettings = existingProject.settingsJson || {};
const project = await prisma.project.update({
where: {
id: projectId,
},
data: {
...(validatedData.name && { name: validatedData.name }),
settingsJson: {
...currentSettings,
...(validatedData.description !== undefined && { description: validatedData.description }),
...validatedData.settings,
},
},
});
logger_1.logger.info(`Project updated: ${project.id}`, {
userId: user.id,
orgId,
changes: validatedData,
});
res.json({
success: true,
data: {
project: {
id: project.id,
name: project.name,
description: project.settingsJson?.description || null,
settings: project.settingsJson,
createdAt: project.createdAt,
},
},
message: 'Project updated successfully',
});
}
catch (error) {
logger_1.logger.error('Failed to update project:', error);
if (error instanceof zod_1.z.ZodError) {
return res.status(400).json({
success: false,
error: 'Validation failed',
details: error.errors,
});
}
res.status(500).json({
success: false,
error: 'Failed to update project',
message: error instanceof Error ? error.message : 'Unknown error',
});
}
});
router.delete('/:projectId', auth_middleware_1.requireAuth, async (req, res) => {
try {
const user = req.user;
const { projectId } = projectParamsSchema.parse(req.params);
const orgId = user.memberships[0]?.orgId;
if (!orgId) {
return res.status(404).json({
success: false,
error: 'No organization found',
});
}
const existingProject = await prisma.project.findFirst({
where: {
id: projectId,
orgId: orgId,
},
include: {
_count: {
select: {
checks: true,
},
},
},
});
if (!existingProject) {
return res.status(404).json({
success: false,
error: 'Project not found',
message: 'Project does not exist or you do not have access to it',
});
}
if (existingProject._count.checks > 0) {
return res.status(400).json({
success: false,
error: 'Cannot delete project with tracking data',
message: `This project has ${existingProject._count.checks} tracking records. Please archive or move the data first.`,
});
}
await prisma.project.delete({
where: {
id: projectId,
},
});
logger_1.logger.info(`Project deleted: ${projectId}`, {
userId: user.id,
orgId,
projectName: existingProject.name,
});
res.json({
success: true,
message: 'Project deleted successfully',
});
}
catch (error) {
logger_1.logger.error('Failed to delete project:', error);
if (error instanceof zod_1.z.ZodError) {
return res.status(400).json({
success: false,
error: 'Invalid project ID',
});
}
res.status(500).json({
success: false,
error: 'Failed to delete project',
message: error instanceof Error ? error.message : 'Unknown error',
});
}
});
exports.default = router;
//# sourceMappingURL=projects.routes.js.map