7.1 KiB
7.1 KiB
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
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)
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
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
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
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
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
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);