Rewrite app: entries → projects with S3 file storage
All checks were successful
ci/woodpecker/push/build Pipeline was successful

Replace flat text entries with project-based structure.
Each project has name, local/corp fields, content textarea,
and file upload (up to 100MB) stored in MinIO S3.
New API: CRUD projects + file download + content copy.
Frontend: two views (project list + project page).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mikhail Kilin
2026-03-18 13:50:28 +03:00
parent d23043a489
commit 570e0ca643
11 changed files with 1586 additions and 201 deletions

View File

@@ -2,13 +2,14 @@
**Репозиторий:** https://git.mikhailkilin.ru/killingdruid/blood-brain-barrier
Веб-приложение для хранения текстовых записей. Пользователь вводит текст через textarea, сохраняет в PostgreSQL, просматривает список всех записей с возможностью удаления и копирования.
Веб-приложение для управления проектами с текстовыми полями и файлами. Главная страница — список проектов, клик по проекту — страница проекта с полями (local, corp), textarea (content) и загрузкой файлов в MinIO S3.
## Стек
- **Frontend:** React + TypeScript + Vite
- **Backend:** Rust (Axum + SQLx)
- **Backend:** Rust (Axum + SQLx + rust-s3)
- **БД:** PostgreSQL
- **Файлы:** MinIO S3
- **Async runtime:** Tokio
## Структура проекта
@@ -17,17 +18,19 @@
blood-brain-barrier/
├── frontend/ # React-приложение (Vite)
│ ├── src/
│ │ ├── App.tsx # Основной компонент: textarea + список записей
│ │ ├── App.tsx # Две view: ProjectList + ProjectPage
│ │ ├── api.ts # Функции для запросов к API
│ │ ├── App.css # Стили
│ │ └── main.tsx
│ ├── Dockerfile # Сборка фронтенда + nginx
│ ├── nginx.conf # Конфиг nginx для раздачи SPA и проксирования API
│ ├── nginx.conf # Nginx: SPA + проксирование API (110MB limit)
│ └── package.json
├── backend/ # Rust API (Axum)
│ ├── src/
│ │ ├── main.rs # Точка входа, подключение к БД, CORS, запуск сервера
│ │ ├── main.rs # Точка входа, AppState, роуты
│ │ ├── db.rs # Подключение к PostgreSQL, init_db
│ │ ── routes.rs # Хендлеры API
│ │ ── s3.rs # Инициализация MinIO S3 bucket
│ │ └── routes.rs # Хендлеры API (projects + файлы)
│ ├── Dockerfile # Сборка бэкенда
│ └── Cargo.toml
├── .woodpecker.yml # CI pipeline
@@ -37,30 +40,36 @@ blood-brain-barrier/
## База данных
Одна таблица `entries`:
```sql
CREATE TABLE entries (
id SERIAL PRIMARY KEY,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
content TEXT NOT NULL
CREATE TABLE IF NOT EXISTS projects (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
local TEXT NOT NULL DEFAULT '',
corp TEXT NOT NULL DEFAULT '',
content TEXT NOT NULL DEFAULT '',
file_name TEXT,
file_key TEXT,
file_size BIGINT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
```
## API
| Метод | Путь | Описание |
|--------|------------------|-------------------------|
| GET | /api/entries | Список записей (id, created_at — без content) |
| POST | /api/entries | Создать запись |
| DELETE | /api/entries/:id | Удалить запись по id |
| GET | /api/entries/:id/content | Получить контент записи (plain text) |
| Метод | Путь | Описание |
|--------|----------------------------|---------------------------------------|
| GET | /api/projects | Список проектов (id, name, created_at)|
| POST | /api/projects | Создать проект (JSON: {name}) |
| GET | /api/projects/:id | Получить проект целиком |
| PUT | /api/projects/:id | Обновить (multipart: local, corp, content, file?) |
| DELETE | /api/projects/:id | Удалить проект + файл из S3 |
| GET | /api/projects/:id/file | Скачать файл |
| GET | /api/projects/:id/content | Получить content (plain text) |
## Frontend
- Сверху: большая `<textarea>` + кнопка "Create"
- Ниже: список всех записей (новые сверху), у каждой кнопки "Delete" и "Copy"
- Копирование — через `navigator.clipboard.writeText()`
- **Главная:** список проектов + инпут для создания нового
- **Страница проекта:** поля Local/Corp, textarea Content, загрузка файла, кнопки Save/Copy text/Download file/Delete
## Команды
@@ -74,3 +83,12 @@ cd backend && cargo run
# PostgreSQL
docker-compose up -d
```
## Env vars (backend)
- `DATABASE_URL` — PostgreSQL connection string
- `S3_ENDPOINT` — MinIO endpoint (default: http://localhost:9000)
- `S3_ACCESS_KEY` — MinIO access key (default: minioadmin)
- `S3_SECRET_KEY` — MinIO secret key (default: minioadmin)
- `S3_BUCKET` — bucket name (default: bbb)
- `S3_REGION` — S3 region (default: us-east-1)