diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..4b725dd
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,3 @@
+ENVIRONMENT=development
+DATABASE_PATH=archivium.db
+ALLOWED_ORIGINS=http://localhost:3000,http://localhost:5173
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..da56cb0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,67 @@
+# Python
+__pycache__/
+*.py[cod]
+*$py.class
+*.so
+.Python
+env/
+venv/
+ENV/
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+
+# Virtual environments
+.venv/
+venv/
+env/
+
+# Database
+*.db
+*.sqlite
+*.sqlite3
+
+# IDE
+.vscode/
+.idea/
+*.swp
+*.swo
+*~
+
+# Environment
+.env
+.env.local
+.env.*.local
+
+# Testing
+.pytest_cache/
+.coverage
+htmlcov/
+
+# OS
+.DS_Store
+Thumbs.db
+
+# Node/Frontend
+node_modules/
+npm-debug.log
+yarn-error.log
+dist/
+build/
+
+# Lock files (optional - uncomment if you want to enforce exact versions)
+# package-lock.json
+# pnpm-lock.yaml
+
diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index 13566b8..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Editor-based HTTP Client requests
-/httpRequests/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml
diff --git a/.idea/Editor.iml b/.idea/Editor.iml
deleted file mode 100644
index d8b3f6c..0000000
--- a/.idea/Editor.iml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
deleted file mode 100644
index 105ce2d..0000000
--- a/.idea/inspectionProfiles/profiles_settings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index 1d3ce46..0000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 3206d78..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..2d9281f
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,83 @@
+# Changelog
+
+## [0.1.1] - 2026-04-09
+
+### Changed
+- Reorganized project structure: moved all modules to `src/` folder
+- Refactored endpoints into separate router modules:
+ - `src/routers/init.py` - System initialization endpoint
+ - `src/routers/login.py` - Authentication endpoint
+ - `src/routers/status.py` - Status check endpoint
+- Reduced `main.py` from 100+ lines to 35 lines (only app configuration)
+- Updated all internal imports to use relative imports within `src/`
+
+### Project Structure
+```
+archivium-backend/
+├── main.py # Entry point (35 lines)
+├── src/
+│ ├── __init__.py
+│ ├── config.py # Configuration
+│ ├── models.py # Database models
+│ ├── schemas.py # Request/response schemas
+│ ├── database.py # Database setup
+│ ├── security.py # Password hashing
+│ └── routers/
+│ ├── __init__.py
+│ ├── init.py # POST /api/init
+│ ├── login.py # POST /api/login
+│ └── status.py # GET /api/status
+├── pyproject.toml
+├── requirements.txt
+└── README.md
+```
+
+---
+
+## [0.1.0] - 2026-04-09
+
+### Changed
+- Removed excessive Polish comments and restructured code for readability
+- Refactored monolithic `main.py` into modular structure:
+ - `config.py` - Environment configuration and CORS settings
+ - `models.py` - SQLAlchemy ORM models
+ - `schemas.py` - Pydantic request/response schemas with validation
+ - `database.py` - Database initialization and session management
+ - `security.py` - Password hashing and recovery key generation
+ - `main.py` - FastAPI application and endpoint handlers
+- Added official Python docstrings for public functions and classes only
+- Improved project metadata with description and version in FastAPI app
+
+### Security Improvements
+- Restricted CORS to explicit allowed origins instead of wildcard ("*")
+- Limited allowed HTTP methods to POST and GET only
+- Restricted allowed headers to Content-Type only
+- Added password validation (minimum 8 characters, maximum 128)
+- Improved error handling with try-except for password verification
+- Database operations now properly managed with dependency injection
+
+### Added
+- `pyproject.toml` for modern Python package management (compatible with uv)
+- `requirements.txt` for traditional pip/env management
+- Proper dependency pinning with specific versions
+- Database initialization on startup event
+- Dependency injection for database sessions via `Depends(get_db)`
+- Recovery key generation moved to dedicated security module
+- Startup lifecycle event to ensure schema creation
+
+### Dependencies
+- fastapi>=0.104.0
+- uvicorn[standard]>=0.24.0
+- pydantic>=2.5.0
+- sqlalchemy>=2.0.0
+- passlib[argon2]>=1.7.4
+
+### Notes
+- SQLite remains in use for development (no encryption at rest)
+- For production deployment, consider:
+ - Using PostgreSQL or equivalent encrypted database
+ - Setting ENVIRONMENT=production env var
+ - Configuring CORS_ORIGINS for specific domains
+ - Enabling HTTPS/SSL
+ - Implementing rate limiting
+ - Adding request logging and monitoring
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..1c7a486
--- /dev/null
+++ b/README.md
@@ -0,0 +1,334 @@
+# 📚 Archivium - System Zarządzania Archiwum
+
+**Archivium** to integrowany system do szyfrowania, przechowywania i wyszukiwania archiwów z bezpiecznym uwierzytelnianiem i interfejsem edytora tekstu.
+
+## 🏗️ Architektura projektu
+
+```
+archivium/
+├── backend/
+│ ├── app/ # Nowoczesny backend FastAPI
+│ │ ├── src/
+│ │ │ ├── config.py # Konfiguracja
+│ │ │ ├── models.py # Modele bazy
+│ │ │ ├── schemas.py # Walidacja
+│ │ │ ├── database.py # Zarządzanie BD
+│ │ │ ├── security.py # Hashing hasła
+│ │ │ └── routers/ # Endpointy API
+│ │ │ ├── init.py
+│ │ │ ├── login.py
+│ │ │ └── status.py
+│ │ ├── main.py # Punkt wejścia (35 linii)
+│ │ └── pyproject.toml
+│ │
+│ └── legacy/ # Stare moduły bazy danych
+│ ├── relational_database.py
+│ └── vector_database.py
+│
+├── frontend/ # React aplikacja (edytor tekstu)
+│ ├── public/
+│ ├── src/
+│ └── package.json
+│
+├── launcher.py # Uruchamiacz całej aplikacji
+├── requirements.txt # Zależności Python
+├── README.md # Ta dokumentacja
+├── CHANGELOG.md # Historia zmian
+└── .git/ # Repozytorium Git
+```
+
+## 🚀 Szybki start
+
+### Uruchomienie całej aplikacji (jedno polecenie)
+
+```bash
+python launcher.py
+```
+
+To uruchomi:
+- ✅ Backend FastAPI (port 8000)
+- ✅ Frontend React (port 3000)
+- ✅ Otworzy przeglądarkę na http://localhost:3000
+
+### Ręczne uruchomienie poszczególnych części
+
+**Backend:**
+```bash
+cd backend/app
+python main.py
+```
+
+**Frontend:**
+```bash
+cd frontend
+npm install
+npm start
+```
+
+## 📡 API Endpoints
+
+### 1. Inicjalizacja systemu
+```http
+POST /api/init
+Content-Type: application/json
+
+{
+ "password": "twoje_bezpieczne_haslo_8znaków_min"
+}
+```
+
+**Response:**
+```json
+{
+ "status": "success",
+ "recovery_key": "a1b2c3d4e5f6...",
+ "message": "System initialized. Save recovery key in safe place."
+}
+```
+
+### 2. Logowanie - hasłem głównym
+```http
+POST /api/login
+Content-Type: application/json
+
+{
+ "password": "twoje_haslo",
+ "is_recovery": false
+}
+```
+
+**Response:**
+```json
+{
+ "status": "success",
+ "message": "Successfully authenticated"
+}
+```
+
+### 3. Logowanie - kluczem awaryjnym
+```http
+POST /api/login
+Content-Type: application/json
+
+{
+ "password": "a1b2c3d4e5f6...",
+ "is_recovery": true
+}
+```
+
+**Response:**
+```json
+{
+ "status": "success",
+ "message": "Authenticated with recovery key. Please change password."
+}
+```
+
+### 4. Sprawdzenie statusu
+```http
+GET /api/status
+```
+
+**Response:**
+```json
+{
+ "is_initialized": true
+}
+```
+
+## 🔐 Bezpieczeństwo
+
+### Zaimplementowane zabezpieczenia:
+- ✅ **Hashing haseł** - Argon2 (type="ID")
+- ✅ **Losowe klucze awaryjne** - 32 znaki hex
+- ✅ **CORS** - ograniczony do zaufanych domen
+- ✅ **Walidacja danych** - Pydantic
+- ✅ **Dwie ścieżki dostępu** - hasło główne + klucz awaryjny
+
+### Zmienne środowiskowe (.env)
+```bash
+ENVIRONMENT=development # development | production
+DATABASE_PATH=archivium.db # lokalizacja bazy
+ALLOWED_ORIGINS=http://localhost:3000,http://localhost:5173
+```
+
+### Rekomendacje produkcyjne:
+1. Użyj **PostgreSQL** zamiast SQLite
+2. Włącz **HTTPS/SSL**
+3. Dodaj **rate limiting**
+4. Włącz **logging i monitoring**
+5. Regularne **backupy** bazy danych
+6. Przechowuj sekrety w zmiennych środowiskowych
+
+## 📚 Szczegółowa dokumentacja struktury
+
+### Backend - Endpointy (src/routers/)
+
+**init.py** - `POST /api/init`
+- Inicjalizuje system
+- Generuje recovery key (32 znaki)
+- Hashuje hasło główne z Argon2
+
+**login.py** - `POST /api/login`
+- Logowanie hasłem głównym lub kluczem awaryjnym
+- Weryfikuje hash haseł
+- Zwraca status autoryzacji
+
+**status.py** - `GET /api/status`
+- Sprawdza czy system zainicjalizowany
+- Zwraca boolean `is_initialized`
+
+### Backend - Core modules (src/)
+
+**config.py** - Konfiguracja
+- CORS configuration
+- DATABASE_PATH z zmiennych środowiskowych
+- ALLOWED_ORIGINS
+
+**models.py** - SQLAlchemy ORM
+- SecurityConfig model
+- Tabela `security_config`
+- Przechowuje hashe haseł i kluczy
+
+**schemas.py** - Pydantic validation
+- InitRequest - walidacja do /api/init
+- LoginRequest - walidacja do /api/login
+
+**database.py** - Zarządzanie bazą
+- SQLite setup
+- Session management
+- `init_db()` - inicjalizuje schemat
+- `get_db()` - dependency injection dla sessionów
+
+**security.py** - Funkcje bezpieczeństwa
+- `hash_password(password: str) -> str`
+- `verify_password(password: str, hash_value: str) -> bool`
+- `generate_recovery_key() -> str`
+
+**main.py** - FastAPI aplikacja (35 linii!)
+- Konfiguracja CORS middleware
+- Include routery
+- Startup event dla init_db()
+
+## 🛠️ Development
+
+### Instalacja dependencies
+
+```bash
+# Backend
+pip install -r requirements.txt
+
+# Lub z uv:
+cd backend/app && uv sync
+
+# Frontend
+cd frontend && npm install
+```
+
+### Testowanie API
+
+```bash
+# Curl - Inicjalizacja
+curl -X POST http://localhost:8000/api/init \
+ -H "Content-Type: application/json" \
+ -d '{"password": "TestPassword123"}'
+
+# Curl - Logowanie
+curl -X POST http://localhost:8000/api/login \
+ -H "Content-Type: application/json" \
+ -d '{"password": "TestPassword123", "is_recovery": false}'
+
+# Status
+curl http://localhost:8000/api/status
+```
+
+### Dokumentacja interaktywna
+
+Gdy serwer działa, otwórz: **http://localhost:8000/docs**
+- Swagger UI do testowania API
+- Automatyczna dokumentacja OpenAPI
+- Try it out - testuj bezpośrednio z przeglądarki
+
+## 📝 Historia zmian
+
+Pełna historia zmian w [CHANGELOG.md](CHANGELOG.md)
+
+### v0.1.1 - Monorepo Integration
+- Reorganizacja całego projektu do struktury monorepo
+- Backend w `backend/app/` (35 linii main.py!)
+- Launcher do uruchamiania całej aplikacji
+- Integracja z starym kodem z `Database/` i `TextEditor/`
+- Kompletna dokumentacja
+
+### v0.1.0 - Refactorization
+- Refaktoryzacja kodu, usunięcie komentarzy
+- Modularyzacja na src/
+- Bezpieczeństwo (CORS, Argon2, walidacja)
+
+## 🐛 Troubleshooting
+
+### Problem: Port 8000 już w użyciu
+```bash
+# Zmień w backend/app/main.py lub użyj:
+cd backend/app && uv run uvicorn main:app --port 8001
+```
+
+### Problem: Frontend nie łączy się z backendem
+Sprawdź w `backend/app/src/config.py`:
+```python
+ALLOWED_ORIGINS = ["http://localhost:3000"]
+```
+
+### Problem: Baza danych uszkodzona
+```bash
+rm archivium.db # Usuń stary plik
+python launcher.py # Przeinicjalizuj
+```
+
+### Problem: npm start nie działa
+```bash
+cd frontend
+rm -rf node_modules package-lock.json
+npm install
+npm start
+```
+
+## 👥 Współpraca (Git)
+
+```bash
+# Clone repozytorium
+git clone http://gitea.archvium.eu:30230/SzymonS/Kod.git
+
+# Stwórz feature branch
+git checkout -b feature/my-feature
+
+# Commit
+git add .
+git commit -am "Add new feature"
+
+# Push
+git push origin feature/my-feature
+```
+
+## 📦 Zależności
+
+### Backend (Python)
+- **FastAPI** (0.104.0+) - Framework
+- **SQLAlchemy** (2.0.0+) - ORM
+- **Pydantic** (2.5.0+) - Walidacja
+- **Passlib[argon2]** (1.7.4+) - Hashing
+- **Uvicorn** (0.24.0+) - ASGI server
+
+### Frontend (Node.js)
+- **React** - UI framework
+- Inne (patrz: `frontend/package.json`)
+
+Pełna lista: [requirements.txt](requirements.txt)
+
+## 📞 Support
+
+Kontakt: SzymonS @ gitea.archvium.eu
+
+---
+
+**Ostatnia aktualizacja:** April 9, 2026
diff --git a/backend/app/main.py b/backend/app/main.py
new file mode 100644
index 0000000..8f67450
--- /dev/null
+++ b/backend/app/main.py
@@ -0,0 +1,35 @@
+from fastapi import FastAPI
+from fastapi.middleware.cors import CORSMiddleware
+
+from src.config import ALLOWED_ORIGINS
+from src.database import init_db
+from src.routers import init, login, status
+
+app = FastAPI(
+ title="Archivium Local Backend",
+ description="Local archive encryption and authentication system",
+ version="0.1.0",
+)
+
+app.add_middleware(
+ CORSMiddleware,
+ allow_origins=ALLOWED_ORIGINS,
+ allow_credentials=True,
+ allow_methods=["POST", "GET"],
+ allow_headers=["Content-Type"],
+)
+
+app.include_router(init.router)
+app.include_router(login.router)
+app.include_router(status.router)
+
+
+@app.on_event("startup")
+def startup():
+ """Initialize database on startup."""
+ init_db()
+
+
+if __name__ == "__main__":
+ import uvicorn
+ uvicorn.run(app, host="127.0.0.1", port=8000)
diff --git a/backend/app/pyproject.toml b/backend/app/pyproject.toml
new file mode 100644
index 0000000..42b944e
--- /dev/null
+++ b/backend/app/pyproject.toml
@@ -0,0 +1,19 @@
+[project]
+name = "archivium-backend"
+version = "0.1.0"
+description = "Local archive encryption and authentication system"
+requires-python = ">=3.9,<3.13"
+dependencies = [
+ "fastapi>=0.104.0",
+ "uvicorn[standard]>=0.24.0",
+ "pydantic>=2.5.0",
+ "sqlalchemy>=2.0.0",
+ "passlib[argon2]>=1.7.4",
+]
+
+[project.optional-dependencies]
+dev = [
+ "pytest>=7.0.0",
+ "pytest-asyncio>=0.21.0",
+ "httpx>=0.25.0",
+]
diff --git a/backend/app/src/__init__.py b/backend/app/src/__init__.py
new file mode 100644
index 0000000..ea83667
--- /dev/null
+++ b/backend/app/src/__init__.py
@@ -0,0 +1 @@
+"""Archivium Backend Application."""
diff --git a/backend/app/src/config.py b/backend/app/src/config.py
new file mode 100644
index 0000000..5de5b9b
--- /dev/null
+++ b/backend/app/src/config.py
@@ -0,0 +1,10 @@
+import os
+
+DB_PATH = os.getenv("DATABASE_PATH", "archivium.db")
+
+ALLOWED_ORIGINS = os.getenv("ALLOWED_ORIGINS", "http://localhost:3000,http://localhost:5173").split(",")
+
+if os.getenv("ENVIRONMENT") == "development":
+ ALLOWED_ORIGINS = ["http://localhost:3000", "http://localhost:5173"]
+elif os.getenv("ENVIRONMENT") == "production":
+ ALLOWED_ORIGINS = os.getenv("CORS_ORIGINS", "").split(",")
diff --git a/backend/app/src/database.py b/backend/app/src/database.py
new file mode 100644
index 0000000..d51db8c
--- /dev/null
+++ b/backend/app/src/database.py
@@ -0,0 +1,28 @@
+from sqlalchemy import create_engine
+from sqlalchemy.orm import sessionmaker, Session
+
+from .config import DB_PATH
+from .models import Base
+
+DATABASE_URL = f"sqlite:///{DB_PATH}"
+
+engine = create_engine(
+ DATABASE_URL,
+ connect_args={"check_same_thread": False},
+)
+
+SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
+
+
+def init_db():
+ """Initialize database schema."""
+ Base.metadata.create_all(bind=engine)
+
+
+def get_db():
+ """Provide database session for dependency injection."""
+ db = SessionLocal()
+ try:
+ yield db
+ finally:
+ db.close()
diff --git a/backend/app/src/models.py b/backend/app/src/models.py
new file mode 100644
index 0000000..9f540ae
--- /dev/null
+++ b/backend/app/src/models.py
@@ -0,0 +1,13 @@
+from sqlalchemy import Column, Integer, String
+from sqlalchemy.orm import declarative_base
+
+Base = declarative_base()
+
+
+class SecurityConfig(Base):
+ """Storage for password and recovery key hashes."""
+ __tablename__ = "security_config"
+
+ id = Column(Integer, primary_key=True, index=True)
+ password_hash = Column(String, nullable=False)
+ recovery_key_hash = Column(String, nullable=False)
diff --git a/backend/app/src/routers/__init__.py b/backend/app/src/routers/__init__.py
new file mode 100644
index 0000000..21109f0
--- /dev/null
+++ b/backend/app/src/routers/__init__.py
@@ -0,0 +1 @@
+"""Routers for Archivium Backend."""
diff --git a/backend/app/src/routers/init.py b/backend/app/src/routers/init.py
new file mode 100644
index 0000000..12fca20
--- /dev/null
+++ b/backend/app/src/routers/init.py
@@ -0,0 +1,39 @@
+import os
+from fastapi import APIRouter, HTTPException, Depends
+from sqlalchemy.orm import Session
+
+from ..database import get_db
+from ..models import SecurityConfig
+from ..schemas import InitRequest
+from ..security import hash_password, generate_recovery_key
+from ..config import DB_PATH
+
+router = APIRouter(prefix="/api", tags=["init"])
+
+
+@router.post("/init")
+def initialize_system(request: InitRequest, db: Session = Depends(get_db)):
+ """Initialize system with master password and generate recovery key."""
+ if os.path.exists(DB_PATH):
+ raise HTTPException(
+ status_code=400,
+ detail="System already initialized",
+ )
+
+ recovery_key = generate_recovery_key()
+ hashed_password = hash_password(request.password)
+ hashed_recovery = hash_password(recovery_key)
+
+ db.add(
+ SecurityConfig(
+ password_hash=hashed_password,
+ recovery_key_hash=hashed_recovery,
+ )
+ )
+ db.commit()
+
+ return {
+ "status": "success",
+ "recovery_key": recovery_key,
+ "message": "System initialized. Save recovery key in safe place.",
+ }
diff --git a/backend/app/src/routers/login.py b/backend/app/src/routers/login.py
new file mode 100644
index 0000000..a1ca6be
--- /dev/null
+++ b/backend/app/src/routers/login.py
@@ -0,0 +1,50 @@
+import os
+from fastapi import APIRouter, HTTPException, Depends
+from sqlalchemy.orm import Session
+
+from ..database import get_db
+from ..models import SecurityConfig
+from ..schemas import LoginRequest
+from ..security import verify_password
+from ..config import DB_PATH
+
+router = APIRouter(prefix="/api", tags=["login"])
+
+
+@router.post("/login")
+def login(request: LoginRequest, db: Session = Depends(get_db)):
+ """Authenticate with master password or recovery key."""
+ if not os.path.exists(DB_PATH):
+ raise HTTPException(
+ status_code=404,
+ detail="System not initialized",
+ )
+
+ config = db.query(SecurityConfig).first()
+ if not config:
+ raise HTTPException(
+ status_code=500,
+ detail="System configuration error",
+ )
+
+ if request.is_recovery:
+ if not verify_password(request.password, config.recovery_key_hash):
+ raise HTTPException(
+ status_code=401,
+ detail="Invalid recovery key",
+ )
+ return {
+ "status": "success",
+ "message": "Authenticated with recovery key. Please change password.",
+ }
+
+ if not verify_password(request.password, config.password_hash):
+ raise HTTPException(
+ status_code=401,
+ detail="Invalid password",
+ )
+
+ return {
+ "status": "success",
+ "message": "Successfully authenticated",
+ }
diff --git a/backend/app/src/routers/status.py b/backend/app/src/routers/status.py
new file mode 100644
index 0000000..edad17f
--- /dev/null
+++ b/backend/app/src/routers/status.py
@@ -0,0 +1,12 @@
+import os
+from fastapi import APIRouter
+
+from ..config import DB_PATH
+
+router = APIRouter(prefix="/api", tags=["status"])
+
+
+@router.get("/status")
+def get_status():
+ """Check if system is initialized."""
+ return {"is_initialized": os.path.exists(DB_PATH)}
diff --git a/backend/app/src/schemas.py b/backend/app/src/schemas.py
new file mode 100644
index 0000000..16d043a
--- /dev/null
+++ b/backend/app/src/schemas.py
@@ -0,0 +1,10 @@
+from pydantic import BaseModel, Field
+
+
+class InitRequest(BaseModel):
+ password: str = Field(..., min_length=8, max_length=128)
+
+
+class LoginRequest(BaseModel):
+ password: str = Field(..., min_length=1, max_length=128)
+ is_recovery: bool = False
diff --git a/backend/app/src/security.py b/backend/app/src/security.py
new file mode 100644
index 0000000..a5d4f23
--- /dev/null
+++ b/backend/app/src/security.py
@@ -0,0 +1,20 @@
+import secrets
+from passlib.hash import argon2
+
+
+def hash_password(password: str) -> str:
+ """Hash password using Argon2."""
+ return argon2.using(type="ID").hash(password)
+
+
+def verify_password(password: str, hash_value: str) -> bool:
+ """Verify password against hash."""
+ try:
+ return argon2.using(type="ID").verify(password, hash_value)
+ except Exception:
+ return False
+
+
+def generate_recovery_key() -> str:
+ """Generate random recovery key (32 hex characters)."""
+ return secrets.token_hex(16)
diff --git a/Database/local_model_miniLM/1_Pooling/config.json b/backend/legacy/local_model_miniLM/1_Pooling/config.json
similarity index 100%
rename from Database/local_model_miniLM/1_Pooling/config.json
rename to backend/legacy/local_model_miniLM/1_Pooling/config.json
diff --git a/Database/local_model_miniLM/README.md b/backend/legacy/local_model_miniLM/README.md
similarity index 100%
rename from Database/local_model_miniLM/README.md
rename to backend/legacy/local_model_miniLM/README.md
diff --git a/Database/local_model_miniLM/config.json b/backend/legacy/local_model_miniLM/config.json
similarity index 100%
rename from Database/local_model_miniLM/config.json
rename to backend/legacy/local_model_miniLM/config.json
diff --git a/Database/local_model_miniLM/config_sentence_transformers.json b/backend/legacy/local_model_miniLM/config_sentence_transformers.json
similarity index 100%
rename from Database/local_model_miniLM/config_sentence_transformers.json
rename to backend/legacy/local_model_miniLM/config_sentence_transformers.json
diff --git a/Database/local_model_miniLM/model.safetensors b/backend/legacy/local_model_miniLM/model.safetensors
similarity index 100%
rename from Database/local_model_miniLM/model.safetensors
rename to backend/legacy/local_model_miniLM/model.safetensors
diff --git a/Database/local_model_miniLM/modules.json b/backend/legacy/local_model_miniLM/modules.json
similarity index 100%
rename from Database/local_model_miniLM/modules.json
rename to backend/legacy/local_model_miniLM/modules.json
diff --git a/Database/local_model_miniLM/sentence_bert_config.json b/backend/legacy/local_model_miniLM/sentence_bert_config.json
similarity index 100%
rename from Database/local_model_miniLM/sentence_bert_config.json
rename to backend/legacy/local_model_miniLM/sentence_bert_config.json
diff --git a/Database/local_model_miniLM/tokenizer.json b/backend/legacy/local_model_miniLM/tokenizer.json
similarity index 100%
rename from Database/local_model_miniLM/tokenizer.json
rename to backend/legacy/local_model_miniLM/tokenizer.json
diff --git a/Database/local_model_miniLM/tokenizer_config.json b/backend/legacy/local_model_miniLM/tokenizer_config.json
similarity index 100%
rename from Database/local_model_miniLM/tokenizer_config.json
rename to backend/legacy/local_model_miniLM/tokenizer_config.json
diff --git a/Database/relational_database.py b/backend/legacy/relational_database.py
similarity index 100%
rename from Database/relational_database.py
rename to backend/legacy/relational_database.py
diff --git a/Database/vector_database.py b/backend/legacy/vector_database.py
similarity index 100%
rename from Database/vector_database.py
rename to backend/legacy/vector_database.py
diff --git a/TextEditor/.gitignore b/frontend/.gitignore
similarity index 100%
rename from TextEditor/.gitignore
rename to frontend/.gitignore
diff --git a/TextEditor/README.md b/frontend/README.md
similarity index 100%
rename from TextEditor/README.md
rename to frontend/README.md
diff --git a/TextEditor/package-lock.json b/frontend/package-lock.json
similarity index 100%
rename from TextEditor/package-lock.json
rename to frontend/package-lock.json
diff --git a/TextEditor/package.json b/frontend/package.json
similarity index 100%
rename from TextEditor/package.json
rename to frontend/package.json
diff --git a/TextEditor/public/favicon.ico b/frontend/public/favicon.ico
similarity index 100%
rename from TextEditor/public/favicon.ico
rename to frontend/public/favicon.ico
diff --git a/TextEditor/public/index.html b/frontend/public/index.html
similarity index 100%
rename from TextEditor/public/index.html
rename to frontend/public/index.html
diff --git a/TextEditor/public/logo192.png b/frontend/public/logo192.png
similarity index 100%
rename from TextEditor/public/logo192.png
rename to frontend/public/logo192.png
diff --git a/TextEditor/public/logo512.png b/frontend/public/logo512.png
similarity index 100%
rename from TextEditor/public/logo512.png
rename to frontend/public/logo512.png
diff --git a/TextEditor/public/manifest.json b/frontend/public/manifest.json
similarity index 100%
rename from TextEditor/public/manifest.json
rename to frontend/public/manifest.json
diff --git a/TextEditor/public/robots.txt b/frontend/public/robots.txt
similarity index 100%
rename from TextEditor/public/robots.txt
rename to frontend/public/robots.txt
diff --git a/TextEditor/src/App.css b/frontend/src/App.css
similarity index 100%
rename from TextEditor/src/App.css
rename to frontend/src/App.css
diff --git a/TextEditor/src/App.js b/frontend/src/App.js
similarity index 100%
rename from TextEditor/src/App.js
rename to frontend/src/App.js
diff --git a/TextEditor/src/App.test.js b/frontend/src/App.test.js
similarity index 100%
rename from TextEditor/src/App.test.js
rename to frontend/src/App.test.js
diff --git a/TextEditor/src/MathField.js b/frontend/src/MathField.js
similarity index 100%
rename from TextEditor/src/MathField.js
rename to frontend/src/MathField.js
diff --git a/TextEditor/src/TextEditor.js b/frontend/src/TextEditor.js
similarity index 100%
rename from TextEditor/src/TextEditor.js
rename to frontend/src/TextEditor.js
diff --git a/TextEditor/src/index.css b/frontend/src/index.css
similarity index 100%
rename from TextEditor/src/index.css
rename to frontend/src/index.css
diff --git a/TextEditor/src/index.js b/frontend/src/index.js
similarity index 100%
rename from TextEditor/src/index.js
rename to frontend/src/index.js
diff --git a/TextEditor/src/logo.svg b/frontend/src/logo.svg
similarity index 100%
rename from TextEditor/src/logo.svg
rename to frontend/src/logo.svg
diff --git a/TextEditor/src/reportWebVitals.js b/frontend/src/reportWebVitals.js
similarity index 100%
rename from TextEditor/src/reportWebVitals.js
rename to frontend/src/reportWebVitals.js
diff --git a/TextEditor/src/setupTests.js b/frontend/src/setupTests.js
similarity index 100%
rename from TextEditor/src/setupTests.js
rename to frontend/src/setupTests.js
diff --git a/launcher.py b/launcher.py
new file mode 100644
index 0000000..34dd25b
--- /dev/null
+++ b/launcher.py
@@ -0,0 +1,83 @@
+"""Archivium Launcher - Uruchamia całą aplikację"""
+import subprocess
+import os
+import sys
+import time
+import webbrowser
+
+
+def install_missing_packages():
+ """Instaluj brakujące pakiety"""
+ packages = ["uvicorn", "fastapi", "sqlalchemy", "passlib[argon2]"]
+ for package in packages:
+ try:
+ __import__(package.split("[")[0].replace("-", "_"))
+ except ImportError:
+ print(f"[*] Instalowanie: {package}...")
+ subprocess.check_call([sys.executable, "-m", "pip", "install", package])
+
+
+def run_archivium():
+ """Uruchom całą aplikację Archivium"""
+ install_missing_packages()
+
+ base_dir = os.path.dirname(os.path.abspath(__file__))
+ backend_dir = os.path.join(base_dir, "backend", "app")
+ frontend_dir = os.path.join(base_dir, "frontend")
+
+ print("\n" + "="*50)
+ print(" ARCHIVIUM - System Zarządzania Archiwum")
+ print("="*50 + "\n")
+
+ print("[1/3] Startuje backend (Port 8000)...")
+ backend_process = subprocess.Popen(
+ [sys.executable, "main.py"],
+ cwd=backend_dir
+ )
+
+ print("[2/3] Startuje frontend (Port 3000)...")
+ try:
+ frontend_process = subprocess.Popen(
+ "npm start",
+ shell=True,
+ cwd=frontend_dir,
+ )
+ except Exception as e:
+ print(f"[!] Uwaga: Nie udało się uruchomić frontendu: {e}")
+ print("[*] Frontend może wymagać: npm install && npm start")
+ frontend_process = None
+
+ print("[3/3] Otwieranie przeglądarki...")
+ time.sleep(3)
+
+ try:
+ webbrowser.open("http://localhost:3000")
+ except Exception as e:
+ print(f"[!] Nie udało się otworzyć przeglądarki: {e}")
+ print("[*] Otwórz ręcznie: http://localhost:3000")
+
+ print("\n" + "="*50)
+ print("✓ Aplikacja uruchomiona!")
+ print(" Backend: http://localhost:8000")
+ print(" Frontend: http://localhost:3000")
+ print(" Docs: http://localhost:8000/docs")
+ print("="*50)
+ print("\nAby zatrzymać: Ctrl+C\n")
+
+ try:
+ backend_process.wait()
+ if frontend_process:
+ frontend_process.wait()
+ except KeyboardInterrupt:
+ print("\n[*] Zatrzymywanie systemu...")
+ backend_process.terminate()
+ if frontend_process:
+ frontend_process.terminate()
+ backend_process.wait()
+ if frontend_process:
+ frontend_process.wait()
+ print("[✓] System zatrzymany")
+
+
+if __name__ == "__main__":
+ run_archivium()
diff --git a/main.py b/main.py
deleted file mode 100644
index df4d0a9..0000000
--- a/main.py
+++ /dev/null
@@ -1,56 +0,0 @@
-import subprocess
-import os
-import sys
-import time
-import webbrowser
-
-
-def install_missing_packages():
- packages = ["uvicorn", "fastapi", "sentence-transformers"]
- for package in packages:
- try:
- __import__(package.replace("-", "_"))
- except ImportError:
- print(f"[*] Instalowanie brakującej biblioteki: {package}...")
- subprocess.check_call([sys.executable, "-m", "pip", "install", package])
-
-
-def run_archivium():
- install_missing_packages()
- base_dir = os.path.dirname(os.path.abspath(__file__))
-
- backend_script = os.path.join(base_dir, "Database", "database.py")
- frontend_dir = os.path.join(base_dir, "TextEditor")
-
- print("\n--- URUCHAMIANIE SYSTEMU ARCHIVIUM ---")
-
- print(f"[*] Startuję bazę danych...")
- backend_process = subprocess.Popen(
- [sys.executable, backend_script],
- cwd=os.path.join(base_dir, "Database")
- )
-
- print(f"[*] Startuję edytor...")
- frontend_process = subprocess.Popen(
- "npm start",
- shell=True,
- cwd=frontend_dir,
- creationflags=subprocess.CREATE_NEW_CONSOLE
- )
-
- print("[*] Oczekiwanie na gotowość...")
- time.sleep(5)
-
- webbrowser.open("http://localhost:3000")
-
- try:
- backend_process.wait()
- frontend_process.wait()
- except KeyboardInterrupt:
- print("\n[*] Zamykanie systemu...")
- backend_process.terminate()
- frontend_process.terminate()
-
-
-if __name__ == "__main__":
- run_archivium()
diff --git a/requirements.txt b/requirements.txt
index 8eac4c7..ba94f40 100644
Binary files a/requirements.txt and b/requirements.txt differ