Initial project setup with Gradle
This commit is contained in:
commit
0a7b382cdb
6 changed files with 622 additions and 0 deletions
319
.kiro/specs/lorep-report-plugin/design.md
Normal file
319
.kiro/specs/lorep-report-plugin/design.md
Normal file
|
|
@ -0,0 +1,319 @@
|
|||
# Design Document: lorep Report Plugin
|
||||
|
||||
## Overview
|
||||
|
||||
Плагин lorep — система репортов для Paper 1.21, написанная на Java 21. Использует Gradle для сборки, SQLite для хранения данных и интегрируется с Discord через webhooks.
|
||||
|
||||
**Технологический стек:**
|
||||
- Java 21
|
||||
- Paper API 1.21
|
||||
- Gradle (Kotlin DSL)
|
||||
- SQLite (встроенная БД) или PostgreSQL (внешняя БД)
|
||||
- HikariCP (connection pool для PostgreSQL)
|
||||
- OkHttp (HTTP клиент для webhooks)
|
||||
|
||||
**Git репозиторий:** https://git.lokili.xyz/loki/lorep.git
|
||||
|
||||
## Architecture
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph Plugin
|
||||
Main[LorepPlugin]
|
||||
CMD[CommandManager]
|
||||
GUI[GuiManager]
|
||||
DB[DatabaseManager]
|
||||
WH[WebhookService]
|
||||
CFG[ConfigManager]
|
||||
end
|
||||
|
||||
subgraph External
|
||||
Discord[Discord Webhook]
|
||||
SQLite[(SQLite DB)]
|
||||
end
|
||||
|
||||
Main --> CMD
|
||||
Main --> GUI
|
||||
Main --> DB
|
||||
Main --> WH
|
||||
Main --> CFG
|
||||
|
||||
CMD --> DB
|
||||
CMD --> WH
|
||||
GUI --> DB
|
||||
WH --> Discord
|
||||
DB --> SQLite
|
||||
CFG --> Main
|
||||
```
|
||||
|
||||
### Структура проекта
|
||||
|
||||
```
|
||||
lorep/
|
||||
├── .gitignore
|
||||
├── build.gradle.kts
|
||||
├── settings.gradle.kts
|
||||
├── src/
|
||||
│ └── main/
|
||||
│ ├── java/
|
||||
│ │ └── dev/
|
||||
│ │ └── loki/
|
||||
│ │ └── lorep/
|
||||
│ │ ├── LorepPlugin.java
|
||||
│ │ ├── command/
|
||||
│ │ │ ├── ReportCommand.java
|
||||
│ │ │ ├── ReportGuiCommand.java
|
||||
│ │ │ └── ReportStatsCommand.java
|
||||
│ │ ├── database/
|
||||
│ │ │ ├── DatabaseManager.java
|
||||
│ │ │ ├── SQLiteDatabaseManager.java
|
||||
│ │ │ ├── PostgreSQLDatabaseManager.java
|
||||
│ │ │ └── Report.java
|
||||
│ │ ├── gui/
|
||||
│ │ │ ├── ReportGui.java
|
||||
│ │ │ └── GuiClickListener.java
|
||||
│ │ ├── webhook/
|
||||
│ │ │ └── DiscordWebhook.java
|
||||
│ │ ├── config/
|
||||
│ │ │ └── ConfigManager.java
|
||||
│ │ └── util/
|
||||
│ │ ├── TimeUtil.java
|
||||
│ │ └── MessageUtil.java
|
||||
│ └── resources/
|
||||
│ ├── plugin.yml
|
||||
│ └── config.yml
|
||||
└── src/
|
||||
└── test/
|
||||
└── java/
|
||||
└── dev/
|
||||
└── loki/
|
||||
└── lorep/
|
||||
├── database/
|
||||
│ └── DatabaseManagerTest.java
|
||||
└── util/
|
||||
└── TimeUtilTest.java
|
||||
```
|
||||
|
||||
## Components and Interfaces
|
||||
|
||||
### 1. LorepPlugin (Main Class)
|
||||
|
||||
```java
|
||||
public final class LorepPlugin extends JavaPlugin {
|
||||
private DatabaseManager databaseManager;
|
||||
private ConfigManager configManager;
|
||||
private DiscordWebhook discordWebhook;
|
||||
|
||||
@Override
|
||||
public void onEnable();
|
||||
|
||||
@Override
|
||||
public void onDisable();
|
||||
|
||||
// Getters for managers
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Report (Data Model)
|
||||
|
||||
```java
|
||||
public record Report(
|
||||
int id,
|
||||
UUID reporterUuid,
|
||||
String reporterName,
|
||||
UUID targetUuid,
|
||||
String targetName,
|
||||
String reason,
|
||||
Instant createdAt
|
||||
) {}
|
||||
```
|
||||
|
||||
### 3. DatabaseManager
|
||||
|
||||
```java
|
||||
public interface DatabaseManager {
|
||||
void initialize();
|
||||
void close();
|
||||
|
||||
void saveReport(Report report);
|
||||
List<Report> getReportsForTarget(UUID targetUuid);
|
||||
List<Report> getAllReports();
|
||||
int getReportCount(UUID targetUuid);
|
||||
boolean hasReported(UUID reporterUuid, UUID targetUuid);
|
||||
List<Report> getReportsPaginated(int page, int pageSize);
|
||||
}
|
||||
|
||||
// Реализации:
|
||||
public class SQLiteDatabaseManager implements DatabaseManager { }
|
||||
public class PostgreSQLDatabaseManager implements DatabaseManager { }
|
||||
```
|
||||
|
||||
### 4. DiscordWebhook
|
||||
|
||||
```java
|
||||
public class DiscordWebhook {
|
||||
public DiscordWebhook(String webhookUrl);
|
||||
|
||||
public void sendReport(Report report);
|
||||
}
|
||||
```
|
||||
|
||||
### 5. ConfigManager
|
||||
|
||||
```java
|
||||
public class ConfigManager {
|
||||
public String getWebhookUrl();
|
||||
public String getDatabasePath();
|
||||
public String getMessage(String key);
|
||||
}
|
||||
```
|
||||
|
||||
### 6. ReportGui
|
||||
|
||||
```java
|
||||
public class ReportGui {
|
||||
public void open(Player player, int page);
|
||||
public ItemStack createReportItem(Report report, int totalReports);
|
||||
}
|
||||
```
|
||||
|
||||
## Data Models
|
||||
|
||||
### Report Entity
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| id | INTEGER | Primary key, auto-increment |
|
||||
| reporter_uuid | TEXT | UUID репортера |
|
||||
| reporter_name | TEXT | Имя репортера |
|
||||
| target_uuid | TEXT | UUID цели |
|
||||
| target_name | TEXT | Имя цели |
|
||||
| reason | TEXT | Причина репорта |
|
||||
| created_at | INTEGER | Unix timestamp создания |
|
||||
|
||||
### SQL Schema
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS reports (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
reporter_uuid TEXT NOT NULL,
|
||||
reporter_name TEXT NOT NULL,
|
||||
target_uuid TEXT NOT NULL,
|
||||
target_name TEXT NOT NULL,
|
||||
reason TEXT NOT NULL,
|
||||
created_at INTEGER NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_target_uuid ON reports(target_uuid);
|
||||
CREATE INDEX idx_reporter_target ON reports(reporter_uuid, target_uuid);
|
||||
```
|
||||
|
||||
### Configuration (config.yml)
|
||||
|
||||
```yaml
|
||||
# Discord Webhook URL
|
||||
webhook-url: ""
|
||||
|
||||
# Database settings
|
||||
database:
|
||||
# Type: sqlite or postgresql
|
||||
type: "sqlite"
|
||||
|
||||
# SQLite settings
|
||||
sqlite:
|
||||
file: "reports.db"
|
||||
|
||||
# PostgreSQL settings
|
||||
postgresql:
|
||||
host: "localhost"
|
||||
port: 5432
|
||||
database: "lorep"
|
||||
username: "lorep"
|
||||
password: "password"
|
||||
pool-size: 10
|
||||
|
||||
# Messages
|
||||
messages:
|
||||
report-sent: "&aРепорт успешно отправлен!"
|
||||
already-reported: "&cВы уже отправляли репорт на этого игрока!"
|
||||
self-report: "&cВы не можете отправить репорт на себя!"
|
||||
player-not-found: "&cИгрок не найден!"
|
||||
no-permission: "&cУ вас нет прав на эту команду!"
|
||||
usage: "&eИспользование: /report <ник> <причина>"
|
||||
```
|
||||
|
||||
## Correctness Properties
|
||||
|
||||
*A property is a characteristic or behavior that should hold true across all valid executions of a system-essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.*
|
||||
|
||||
### Property 1: Report Creation Integrity
|
||||
*For any* valid reporter UUID, target UUID, and reason string, creating a report and then querying reports for that target SHALL return a list containing the created report with matching fields.
|
||||
**Validates: Requirements 1.1, 2.1**
|
||||
|
||||
### Property 2: Duplicate Report Prevention
|
||||
*For any* reporter-target pair, if a report already exists from that reporter to that target, attempting to create another report SHALL be rejected.
|
||||
**Validates: Requirements 1.2**
|
||||
|
||||
### Property 3: Report Persistence Round-Trip
|
||||
*For any* set of reports saved to the database, reloading the database SHALL return the same reports with identical data.
|
||||
**Validates: Requirements 2.2**
|
||||
|
||||
### Property 4: Report Ordering
|
||||
*For any* collection of reports with different timestamps, querying all reports SHALL return them sorted by creation timestamp in descending order (newest first).
|
||||
**Validates: Requirements 2.3**
|
||||
|
||||
### Property 5: Webhook Payload Completeness
|
||||
*For any* report sent to the webhook, the payload SHALL contain reporter name, target name, reason, and formatted timestamp.
|
||||
**Validates: Requirements 3.1**
|
||||
|
||||
### Property 6: Pagination Correctness
|
||||
*For any* list of N reports and page size P, requesting page K SHALL return at most P reports starting from index K*P, and the total page count SHALL equal ceil(N/P).
|
||||
**Validates: Requirements 4.4**
|
||||
|
||||
### Property 7: Report Count Accuracy
|
||||
*For any* target UUID, the report count returned by getReportCount SHALL equal the actual number of reports in the database for that target.
|
||||
**Validates: Requirements 5.1**
|
||||
|
||||
### Property 8: Permission Enforcement
|
||||
*For any* command execution, if the player lacks the required permission, the command SHALL be denied and return false.
|
||||
**Validates: Requirements 6.1, 6.2, 6.3**
|
||||
|
||||
### Property 9: Configuration Parsing
|
||||
*For any* valid config.yml file, parsing SHALL correctly extract webhook URL and database path values.
|
||||
**Validates: Requirements 7.1, 7.3, 7.4**
|
||||
|
||||
## Error Handling
|
||||
|
||||
| Scenario | Handling |
|
||||
|----------|----------|
|
||||
| Database connection failure | Log error, disable plugin gracefully |
|
||||
| Webhook request failure | Log warning, continue operation |
|
||||
| Invalid player name | Return error message to player |
|
||||
| Missing config values | Use default values |
|
||||
| SQL exceptions | Log error, return empty result |
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Property-Based Testing Library
|
||||
- **JQwik** — библиотека для property-based тестирования в Java
|
||||
- Минимум 100 итераций на каждый property test
|
||||
|
||||
### Unit Tests
|
||||
- DatabaseManager: CRUD операции, pagination
|
||||
- TimeUtil: форматирование времени
|
||||
- ConfigManager: парсинг конфигурации
|
||||
|
||||
### Property-Based Tests
|
||||
Каждый property test должен быть аннотирован:
|
||||
```java
|
||||
// **Feature: lorep-report-plugin, Property 1: Report Creation Integrity**
|
||||
@Property(tries = 100)
|
||||
void reportCreationIntegrity(@ForAll UUID reporter, @ForAll UUID target, @ForAll String reason) {
|
||||
// test implementation
|
||||
}
|
||||
```
|
||||
|
||||
### Integration Tests
|
||||
- Полный цикл создания репорта
|
||||
- GUI открытие и навигация
|
||||
- Webhook отправка (с mock сервером)
|
||||
Loading…
Add table
Add a link
Reference in a new issue