🚀 Initial commit: Biveki Day Bot with Docker deployment

 Features:
- 🤖 Telegram bot for task management between programmer and girlfriend
- 📝 Task creation with types (personal/shared) and priorities
-  Time-based reminders and notifications
- 📊 Statistics and progress tracking
- 🤝 Shared tasks for couples

🛠 Tech Stack:
- Backend: NestJS + TypeScript
- Database: PostgreSQL + TypeORM
- Bot: Telegraf
- Deployment: Docker + Docker Compose

🐳 Docker Deployment:
- Multi-stage Dockerfile for optimized builds
- Docker Compose with environment variables
- Health checks and automatic restarts
- Production-ready configuration

📦 Files included:
- Complete NestJS application
- Docker deployment configuration
- Environment variables setup
- Deployment scripts and documentation
- Health monitoring and logging
This commit is contained in:
Bivekich
2025-06-26 21:40:27 +03:00
commit 0ce19f8182
27 changed files with 15641 additions and 0 deletions

141
src/entities/task.entity.ts Normal file
View File

@ -0,0 +1,141 @@
import {
Entity,
Column,
PrimaryGeneratedColumn,
ManyToOne,
CreateDateColumn,
UpdateDateColumn,
JoinColumn,
} from 'typeorm';
import { User } from './user.entity';
export enum TaskStatus {
PENDING = 'pending',
IN_PROGRESS = 'in_progress',
COMPLETED = 'completed',
CANCELLED = 'cancelled',
}
export enum TaskPriority {
LOW = 'low',
MEDIUM = 'medium',
HIGH = 'high',
URGENT = 'urgent',
}
export enum TaskType {
PERSONAL = 'personal', // Личная задача (только для одного пользователя)
SHARED = 'shared', // Общая задача (для обоих)
}
@Entity('tasks')
export class Task {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@Column({ type: 'text', nullable: true })
description: string;
@Column({
type: 'enum',
enum: TaskStatus,
default: TaskStatus.PENDING,
})
status: TaskStatus;
@Column({
type: 'enum',
enum: TaskPriority,
default: TaskPriority.MEDIUM,
})
priority: TaskPriority;
@Column({
type: 'enum',
enum: TaskType,
default: TaskType.PERSONAL,
})
type: TaskType;
@Column({ type: 'timestamp', nullable: true })
dueDate: Date;
@Column({ type: 'timestamp', nullable: true })
reminderDate: Date;
@Column({ default: false })
reminderSent: boolean;
// Пользователь, которому назначена задача
@ManyToOne(() => User, (user) => user.assignedTasks, { nullable: true })
@JoinColumn({ name: 'assigned_to_id' })
assignedTo: User;
@Column({ name: 'assigned_to_id', nullable: true })
assignedToId: number;
// Пользователь, который создал задачу
@ManyToOne(() => User, (user) => user.createdTasks)
@JoinColumn({ name: 'created_by_id' })
createdBy: User;
@Column({ name: 'created_by_id' })
createdById: number;
@CreateDateColumn()
createdAt: Date;
@UpdateDateColumn()
updatedAt: Date;
// Метод для получения эмодзи статуса
getStatusEmoji(): string {
switch (this.status) {
case TaskStatus.PENDING:
return '⏳';
case TaskStatus.IN_PROGRESS:
return '🔄';
case TaskStatus.COMPLETED:
return '✅';
case TaskStatus.CANCELLED:
return '❌';
default:
return '📝';
}
}
// Метод для получения эмодзи приоритета
getPriorityEmoji(): string {
switch (this.priority) {
case TaskPriority.LOW:
return '🟢';
case TaskPriority.MEDIUM:
return '🟡';
case TaskPriority.HIGH:
return '🟠';
case TaskPriority.URGENT:
return '🔴';
default:
return '⚪';
}
}
// Метод для получения эмодзи типа задачи
getTypeEmoji(): string {
return this.type === TaskType.SHARED ? '🤝' : '👤';
}
// Проверка, нужно ли отправить напоминание
shouldSendReminder(): boolean {
return (
!this.reminderSent &&
this.reminderDate &&
new Date() >= this.reminderDate &&
this.status !== TaskStatus.COMPLETED &&
this.status !== TaskStatus.CANCELLED
);
}
}