push
This commit is contained in:
@@ -0,0 +1,268 @@
|
||||
### **Техническое задание №1: Основа проекта, модели данных и репозитории**
|
||||
|
||||
**Цель:** Создать фундамент backend-приложения для модуля SMM-автоматизации. На этом этапе необходимо инициализировать проект, определить структуру базы данных с помощью JPA-сущностей и создать репозитории для доступа к данным.
|
||||
|
||||
---
|
||||
|
||||
## 1\. Инициализация проекта
|
||||
|
||||
- **Задача:** Создать новый проект на базе **Spring Boot**.
|
||||
- **Технологический стек:**
|
||||
- **Фреймворк:** Spring Boot 3.x
|
||||
- **Язык:** Java 17 (или выше)
|
||||
- **Сборщик:** Maven
|
||||
- **Артефакт:** `smm-automation-service`
|
||||
|
||||
---
|
||||
|
||||
## 2\. Зависимости
|
||||
|
||||
В `pom.xml` необходимо добавить следующие ключевые зависимости:
|
||||
|
||||
- **Spring Web:** для создания REST-контроллеров.
|
||||
- **Spring Data JPA:** для работы с базой данных через сущности.
|
||||
- **PostgreSQL Driver:** для подключения к базе данных PostgreSQL.
|
||||
- **Lombok:** для сокращения шаблонного кода в моделях (геттеры, сеттеры, конструкторы).
|
||||
- **Hibernate Types:** для поддержки типа данных JSON в PostgreSQL.
|
||||
|
||||
---
|
||||
|
||||
## 3\. Модели данных (JPA Entities)
|
||||
|
||||
Необходимо создать Java-классы, описывающие таблицы в базе данных, со всеми указанными полями, типами и связями.
|
||||
|
||||
### `Channel.java`
|
||||
|
||||
Канал для публикации (Telegram, VK и т.д.).
|
||||
|
||||
```java
|
||||
import jakarta.persistence.*;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Table(name = "channels")
|
||||
public class Channel {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private UUID id;
|
||||
|
||||
private String name; // e.g., "Telegram Official"
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
private ChannelType type; // ENUM: TELEGRAM, VK, INSTAGRAM
|
||||
|
||||
private String apiKeyRef; // Ссылка на secret в Vault или аналоге
|
||||
|
||||
private boolean isActive;
|
||||
}
|
||||
|
||||
// Необходимо также создать Enum ChannelType
|
||||
public enum ChannelType {
|
||||
TELEGRAM, VK, INSTAGRAM
|
||||
}
|
||||
```
|
||||
|
||||
### `Campaign.java`
|
||||
|
||||
Маркетинговая кампания.
|
||||
|
||||
```java
|
||||
import jakarta.persistence.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Table(name = "campaigns")
|
||||
public class Campaign {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private UUID id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String goal;
|
||||
|
||||
private BigDecimal budget;
|
||||
|
||||
private ZonedDateTime startAt;
|
||||
|
||||
private ZonedDateTime endAt;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
private CampaignStatus status; // ENUM: PLANNED, ACTIVE, COMPLETED
|
||||
}
|
||||
|
||||
// Enum CampaignStatus
|
||||
public enum CampaignStatus {
|
||||
PLANNED, ACTIVE, COMPLETED
|
||||
}
|
||||
```
|
||||
|
||||
### `ContentQueue.java`
|
||||
|
||||
Очередь контента для публикации.
|
||||
|
||||
```java
|
||||
import jakarta.persistence.*;
|
||||
import org.hibernate.annotations.JdbcTypeCode;
|
||||
import org.hibernate.type.SqlTypes;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Table(name = "content_queue")
|
||||
public class ContentQueue {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private UUID id;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "campaign_id")
|
||||
private Campaign campaign;
|
||||
|
||||
private String locale; // e.g., "ru", "kk"
|
||||
|
||||
private String topic;
|
||||
|
||||
@JdbcTypeCode(SqlTypes.JSON)
|
||||
@Column(columnDefinition = "jsonb")
|
||||
private String postDraft; // JSON: { "title": "...", "body": "...", "hashtags": [...] }
|
||||
|
||||
@JdbcTypeCode(SqlTypes.JSON)
|
||||
@Column(columnDefinition = "jsonb")
|
||||
private String assetsRefs; // JSON: ["path/to/image1.jpg"]
|
||||
|
||||
private ZonedDateTime scheduledAt;
|
||||
|
||||
private int priority;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
private ContentStatus status; // ENUM: DRAFT, PENDING_APPROVAL, APPROVED, PUBLISHED, FAILED
|
||||
}
|
||||
|
||||
// Enum ContentStatus
|
||||
public enum ContentStatus {
|
||||
DRAFT, PENDING_APPROVAL, APPROVED, PUBLISHED, FAILED
|
||||
}
|
||||
```
|
||||
|
||||
### `Message.java`
|
||||
|
||||
Факт публикации сообщения.
|
||||
|
||||
```java
|
||||
import jakarta.persistence.*;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Table(name = "messages")
|
||||
public class Message {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private UUID id;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "channel_id")
|
||||
private Channel channel;
|
||||
|
||||
@OneToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "content_id")
|
||||
private ContentQueue content;
|
||||
|
||||
private String externalId; // ID поста в соцсети
|
||||
|
||||
private String url;
|
||||
|
||||
private ZonedDateTime postedAt;
|
||||
}
|
||||
```
|
||||
|
||||
### `KpiSnapshot.java`
|
||||
|
||||
Срезы по ключевым метрикам.
|
||||
|
||||
```java
|
||||
import jakarta.persistence.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Table(name = "kpi_snapshots")
|
||||
public class KpiSnapshot {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private UUID id;
|
||||
|
||||
private LocalDate date;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "channel_id")
|
||||
private Channel channel;
|
||||
|
||||
private String metric; // e.g., "CTR", "ER", "LEADS"
|
||||
|
||||
private BigDecimal value;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4\. Репозитории (Spring Data JPA)
|
||||
|
||||
Для каждой созданной сущности необходимо создать соответствующий интерфейс-репозиторий для взаимодействия с базой данных.
|
||||
|
||||
- `ChannelRepository.java`
|
||||
- `CampaignRepository.java`
|
||||
- `ContentQueueRepository.java`
|
||||
- `MessageRepository.java`
|
||||
- `KpiSnapshotRepository.java`
|
||||
|
||||
**Пример для `CampaignRepository`:**
|
||||
|
||||
```java
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import java.util.UUID;
|
||||
|
||||
@Repository
|
||||
public interface CampaignRepository extends JpaRepository<Campaign, UUID> {
|
||||
// Здесь в будущем можно будет добавлять кастомные методы для запросов
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5\. Конфигурация базы данных
|
||||
|
||||
В файле `application.properties` или `application.yml` необходимо указать настройки для подключения к локальной или dev-базе данных PostgreSQL.
|
||||
|
||||
**Пример для `application.yml`:**
|
||||
|
||||
```yaml
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:postgresql://localhost:5432/smm_automation_db
|
||||
username: your_username
|
||||
password: your_password
|
||||
jpa:
|
||||
hibernate:
|
||||
ddl-auto: update # На время разработки, для prod использовать 'validate'
|
||||
properties:
|
||||
hibernate:
|
||||
dialect: org.hibernate.dialect.PostgreSQLDialect
|
||||
format_sql: true
|
||||
show-sql: true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Критерии выполнения
|
||||
|
||||
- Проект Spring Boot успешно создан и запускается без ошибок.
|
||||
- Все 5 JPA-сущностей и 3 Enum'а созданы в проекте.
|
||||
- Для каждой сущности создан соответствующий Spring Data JPA репозиторий.
|
||||
- Приложение успешно подключается к базе данных PostgreSQL.
|
||||
- При запуске приложения Hibernate автоматически создает или обновляет таблицы в базе данных в соответствии с описанными моделями.
|
||||
Reference in New Issue
Block a user