← Назад к вопросам
Приведи пример проекта который реализовал в последнее время
1.6 Junior🔥 171 комментариев
#Soft skills и опыт работы
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Проект: Real-Time Collaborative Task Manager
Описание проекта
Недавно реализовал полнофункциональный веб-приложение для управления задачами в команде с real-time синхронизацией. Система позволяет пользователям создавать проекты, добавлять задачи, назначать их коллегам и видеть обновления в реальном времени.
Стек технологий
- Backend: Node.js + Express.js + TypeScript
- Database: PostgreSQL с миграциями Goose
- Real-time: WebSocket (Socket.io) для синхронизации
- Authentication: JWT + Refresh tokens
- Queue: RabbitMQ для асинхронных задач
- Deployment: Docker + Docker Compose + Dokku
Архитектура Backend
// src/domain/Task/Task.ts - Domain Entity
export class Task {
constructor(
public id: string,
public title: string,
public description: string,
public status: "todo" | "in-progress" | "done",
public assignedTo: string,
public dueDate: Date,
public projectId: string
) {}
complete(): void {
this.status = "done";
}
reassign(userId: string): void {
this.assignedTo = userId;
}
}
// src/application/usecase/CreateTaskUseCase.ts
export class CreateTaskUseCase {
constructor(
private taskRepository: ITaskRepository,
private projectRepository: IProjectRepository,
private eventPublisher: IEventPublisher
) {}
async execute(command: CreateTaskCommand): Promise<Task> {
// 1. Валидация проекта
const project = await this.projectRepository.findById(command.projectId);
if (!project) {
throw new ProjectNotFoundError();
}
// 2. Создание задачи
const task = new Task(
uuid(),
command.title,
command.description,
"todo",
command.assignedTo,
command.dueDate,
command.projectId
);
// 3. Сохранение
await this.taskRepository.save(task);
// 4. Публикация события для real-time синхронизации
await this.eventPublisher.publish("task.created", {
taskId: task.id,
projectId: task.projectId,
title: task.title
});
return task;
}
}
Real-Time синхронизация через WebSocket
// src/presentation/websocket/TaskNamespace.ts
export class TaskNamespace {
constructor(
private io: Server,
private createTaskUseCase: CreateTaskUseCase,
private updateTaskUseCase: UpdateTaskUseCase
) {}
initialize(): void {
this.io.on("connection", (socket) => {
// Подписываемся на проект
socket.on("subscribe:project", (projectId: string) => {
socket.join(`project:${projectId}`);
});
// Создание новой задачи в real-time
socket.on("task:create", async (data) => {
const task = await this.createTaskUseCase.execute(data);
// Отправляем обновление всем в проекте
this.io.to(`project:${data.projectId}`).emit("task:created", {
id: task.id,
title: task.title,
assignedTo: task.assignedTo
});
});
// Обновление статуса задачи
socket.on("task:update-status", async (data) => {
const task = await this.updateTaskUseCase.execute(data);
this.io.to(`project:${task.projectId}`).emit("task:status-changed", {
taskId: task.id,
newStatus: task.status,
updatedAt: new Date()
});
});
});
}
}
API REST endpoints
// src/presentation/http/TaskController.ts
export class TaskController {
constructor(private taskService: TaskService) {}
// GET /api/v1/tasks?projectId=xxx
async listTasks(req: Request, res: Response) {
const tasks = await this.taskService.findByProject(req.query.projectId);
res.json(tasks);
}
// POST /api/v1/tasks
async createTask(req: Request, res: Response) {
const task = await this.taskService.create(req.body);
res.status(201).json(task);
}
// PATCH /api/v1/tasks/:id
async updateTask(req: Request, res: Response) {
const task = await this.taskService.update(req.params.id, req.body);
res.json(task);
}
// DELETE /api/v1/tasks/:id
async deleteTask(req: Request, res: Response) {
await this.taskService.delete(req.params.id);
res.status(204).send();
}
}
Миграция БД (Goose)
-- migrations/0001_create_tasks_table.sql
CREATE TABLE tasks (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
title VARCHAR(255) NOT NULL,
description TEXT,
status VARCHAR(20) NOT NULL DEFAULT "todo",
assigned_to UUID REFERENCES users(id),
due_date TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_tasks_project_id ON tasks(project_id);
CREATE INDEX idx_tasks_assigned_to ON tasks(assigned_to);
Docker Compose для локальной разработки
version: "3.8"
services:
app:
build: .
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://user:pass@postgres:5432/tasks
REDIS_URL: redis://redis:6379
depends_on:
- postgres
- redis
- rabbitmq
postgres:
image: postgres:15
environment:
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7
rabbitmq:
image: rabbitmq:3.12-management
Результаты проекта
- Обработка 500+ одновременных WebSocket соединений
- Синхронизация в реальном времени (< 100ms задержка)
- Полное покрытие тестами (92%)
- Развертывание на production через Dokku