199 lines
7.1 KiB
Markdown
199 lines
7.1 KiB
Markdown
# BackPRO - Schemat bazy danych
|
|
|
|
## Diagram relacji
|
|
|
|
```
|
|
users
|
|
↓ (brak FK, niezależna tabela)
|
|
|
|
global_topics (parent_id → self) ← hierarchia 2-poziomowa
|
|
↓
|
|
└── topics.global_topic_id (opcjonalne powiązanie)
|
|
|
|
sites ←──── topics ←──── articles
|
|
│ │
|
|
│ ├── global_topic_id (FK → global_topics, opcjonalne)
|
|
│ └── wp_category_id (mapowanie na kategorię WP)
|
|
│
|
|
└── last_published_at (tracking publikacji)
|
|
|
|
settings (klucz-wartość, konfiguracja globalna)
|
|
```
|
|
|
|
## Tabele
|
|
|
|
### `users` - Użytkownicy systemu
|
|
|
|
```sql
|
|
CREATE TABLE users (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
username VARCHAR(50) NOT NULL UNIQUE,
|
|
password_hash VARCHAR(255) NOT NULL,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
```
|
|
|
|
| Kolumna | Typ | Opis |
|
|
|---------|-----|------|
|
|
| id | INT AUTO_INCREMENT PK | Identyfikator |
|
|
| username | VARCHAR(50) UNIQUE NOT NULL | Login użytkownika |
|
|
| password_hash | VARCHAR(255) NOT NULL | Hash hasła (bcrypt) |
|
|
| created_at | DATETIME | Data utworzenia |
|
|
|
|
### `global_topics` - Biblioteka tematów (2-poziomowa hierarchia)
|
|
|
|
```sql
|
|
CREATE TABLE global_topics (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
parent_id INT NULL,
|
|
name VARCHAR(255) NOT NULL,
|
|
description TEXT NULL,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (parent_id) REFERENCES global_topics(id) ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
```
|
|
|
|
| Kolumna | Typ | Opis |
|
|
|---------|-----|------|
|
|
| id | INT AUTO_INCREMENT PK | Identyfikator |
|
|
| parent_id | INT NULL FK → self | NULL = kategoria nadrzędna, wartość = subtemat |
|
|
| name | VARCHAR(255) | Nazwa tematu/kategorii |
|
|
| description | TEXT NULL | Opis / wytyczne dla AI |
|
|
| created_at | DATETIME | Data dodania |
|
|
|
|
**Preinstalowane kategorie:** Polityka, Zdrowie, Sport, Technologia, Biznes i Finanse, Rozrywka, Nauka, Edukacja, Podróże, Motoryzacja, Dom i Ogród, Kuchnia, Moda i Uroda, Prawo (+ ~50 subtematów).
|
|
|
|
### `sites` - Strony WordPress
|
|
|
|
```sql
|
|
CREATE TABLE sites (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
name VARCHAR(255) NOT NULL,
|
|
url VARCHAR(255) NOT NULL,
|
|
api_user VARCHAR(100) NOT NULL,
|
|
api_token VARCHAR(255) NOT NULL,
|
|
publish_interval_days INT NOT NULL DEFAULT 3,
|
|
last_published_at DATETIME NULL,
|
|
is_active TINYINT(1) NOT NULL DEFAULT 1,
|
|
is_multisite TINYINT(1) NOT NULL DEFAULT 0,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
```
|
|
|
|
| Kolumna | Typ | Opis |
|
|
|---------|-----|------|
|
|
| id | INT AUTO_INCREMENT PK | Identyfikator |
|
|
| name | VARCHAR(255) | Nazwa strony (wyświetlana w panelu) |
|
|
| url | VARCHAR(255) | URL WordPressa (np. https://example.com) |
|
|
| api_user | VARCHAR(100) | Login użytkownika WP do REST API |
|
|
| api_token | VARCHAR(255) | Application Password WP |
|
|
| publish_interval_days | INT DEFAULT 3 | Co ile dni publikować nowy artykuł |
|
|
| last_published_at | DATETIME NULL | Data ostatniej publikacji |
|
|
| is_active | TINYINT(1) DEFAULT 1 | Czy strona jest aktywna (0/1) |
|
|
| is_multisite | TINYINT(1) DEFAULT 0 | Czy wielotematyczna (0/1) |
|
|
| created_at | DATETIME | Data dodania |
|
|
|
|
### `topics` - Tematy
|
|
|
|
```sql
|
|
CREATE TABLE topics (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
site_id INT NOT NULL,
|
|
name VARCHAR(255) NOT NULL,
|
|
description TEXT NULL,
|
|
wp_category_id INT NULL,
|
|
article_count INT NOT NULL DEFAULT 0,
|
|
is_active TINYINT(1) NOT NULL DEFAULT 1,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (site_id) REFERENCES sites(id) ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
```
|
|
|
|
| Kolumna | Typ | Opis |
|
|
|---------|-----|------|
|
|
| id | INT AUTO_INCREMENT PK | Identyfikator |
|
|
| site_id | INT FK → sites.id | Strona, do której przypisany temat |
|
|
| name | VARCHAR(255) | Nazwa tematu (np. "Ogrodnictwo", "DIY") |
|
|
| description | TEXT NULL | Opis/wytyczne dla AI (jak pisać artykuły) |
|
|
| wp_category_id | INT NULL | ID kategorii w WordPressie (mapowanie) |
|
|
| article_count | INT DEFAULT 0 | Licznik opublikowanych artykułów z tego tematu |
|
|
| is_active | TINYINT(1) DEFAULT 1 | Czy temat aktywny |
|
|
| created_at | DATETIME | Data dodania |
|
|
|
|
**Uwaga:** `article_count` jest zinkrementalizowanym licznikiem, aktualizowanym po każdej publikacji. Służy do równomiernego rozkładu tematów (TopicBalancer).
|
|
|
|
### `articles` - Artykuły
|
|
|
|
```sql
|
|
CREATE TABLE articles (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
site_id INT NOT NULL,
|
|
topic_id INT NOT NULL,
|
|
title VARCHAR(500) NOT NULL,
|
|
content TEXT NOT NULL,
|
|
wp_post_id INT NULL,
|
|
image_url VARCHAR(500) NULL,
|
|
status ENUM('generated', 'published', 'failed') NOT NULL DEFAULT 'generated',
|
|
ai_model VARCHAR(50) NULL,
|
|
prompt_used TEXT NULL,
|
|
error_message TEXT NULL,
|
|
published_at DATETIME NULL,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (site_id) REFERENCES sites(id) ON DELETE CASCADE,
|
|
FOREIGN KEY (topic_id) REFERENCES topics(id) ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
```
|
|
|
|
| Kolumna | Typ | Opis |
|
|
|---------|-----|------|
|
|
| id | INT AUTO_INCREMENT PK | Identyfikator |
|
|
| site_id | INT FK → sites.id | Strona docelowa |
|
|
| topic_id | INT FK → topics.id | Temat artykułu |
|
|
| title | VARCHAR(500) | Tytuł artykułu |
|
|
| content | TEXT | Treść artykułu (HTML) |
|
|
| wp_post_id | INT NULL | ID posta w WordPressie (po publikacji) |
|
|
| image_url | VARCHAR(500) NULL | URL wygenerowanego obrazka |
|
|
| status | ENUM | Status: generated, published, failed |
|
|
| ai_model | VARCHAR(50) | Model AI użyty do wygenerowania |
|
|
| prompt_used | TEXT | Pełny prompt wysłany do AI |
|
|
| error_message | TEXT NULL | Treść błędu (jeśli status = failed) |
|
|
| published_at | DATETIME NULL | Data publikacji na WordPressie |
|
|
| created_at | DATETIME | Data wygenerowania |
|
|
|
|
### `settings` - Ustawienia globalne
|
|
|
|
```sql
|
|
CREATE TABLE settings (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
`key` VARCHAR(100) NOT NULL UNIQUE,
|
|
value TEXT NULL
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
```
|
|
|
|
| Kolumna | Typ | Opis |
|
|
|---------|-----|------|
|
|
| id | INT AUTO_INCREMENT PK | Identyfikator |
|
|
| key | VARCHAR(100) UNIQUE | Klucz ustawienia |
|
|
| value | TEXT | Wartość ustawienia |
|
|
|
|
**Domyślne ustawienia:**
|
|
| Klucz | Wartość | Opis |
|
|
|-------|---------|------|
|
|
| openai_api_key | sk-... | Klucz API OpenAI |
|
|
| openai_model | gpt-4o | Model do generowania artykułów |
|
|
| freepik_api_key | ... | Klucz API Freepik |
|
|
| image_provider | freepik | Dostawca obrazków (freepik/unsplash/pexels) |
|
|
| article_min_words | 800 | Min. długość artykułu |
|
|
| article_max_words | 1200 | Max. długość artykułu |
|
|
|
|
## Indeksy
|
|
|
|
```sql
|
|
CREATE INDEX idx_topics_site_id ON topics(site_id);
|
|
CREATE INDEX idx_articles_site_id ON articles(site_id);
|
|
CREATE INDEX idx_articles_topic_id ON articles(topic_id);
|
|
CREATE INDEX idx_articles_status ON articles(status);
|
|
CREATE INDEX idx_sites_is_active ON sites(is_active);
|
|
CREATE INDEX idx_sites_last_published ON sites(last_published_at);
|
|
```
|