chore: Archive legacy docs and backup files, prepare for codebase cleanup v2.0
This commit is contained in:
95
archive/2026.02.18 Archive_old_mapps/_legacy_backup/build_complex_db.py
Executable file
95
archive/2026.02.18 Archive_old_mapps/_legacy_backup/build_complex_db.py
Executable file
@@ -0,0 +1,95 @@
|
||||
import asyncio
|
||||
import os
|
||||
from sqlalchemy.ext.asyncio import create_async_engine
|
||||
from sqlalchemy import text
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
# Cím beállítása
|
||||
raw_url = os.getenv("DATABASE_URL")
|
||||
if not raw_url:
|
||||
raw_url = "postgresql://admin:PASSWORD_111@postgres-db:5432/service_finder"
|
||||
DATABASE_URL = raw_url.replace("postgresql://", "postgresql+asyncpg://").replace("/service_finder_db", "/service_finder")
|
||||
|
||||
async def build_db():
|
||||
print(f"🔌 Kapcsolódás a rendszerhez...")
|
||||
engine = create_async_engine(DATABASE_URL)
|
||||
|
||||
async with engine.begin() as conn:
|
||||
print("🏗️ 'DATA' séma előkészítése...")
|
||||
await conn.execute(text("CREATE SCHEMA IF NOT EXISTS data;"))
|
||||
|
||||
# 1. FELHASZNÁLÓK TÁBLA (Céges/Magán logika)
|
||||
print("👤 Users tábla létrehozása...")
|
||||
await conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS data.users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
email VARCHAR(255) UNIQUE NOT NULL,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
role VARCHAR(20) DEFAULT 'PRIVATE', -- 'PRIVATE', 'COMPANY', 'ADMIN'
|
||||
company_name VARCHAR(255), -- Ha cég
|
||||
tax_number VARCHAR(50), -- Ha cég
|
||||
is_active BOOLEAN DEFAULT FALSE, -- Email megerősítésig
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
"""))
|
||||
|
||||
# 2. JÁRMŰ TÖRZS (A Fizikai Vas - Tulajdonos nélkül!)
|
||||
print("🚗 Vehicles tábla létrehozása (A Vas)...")
|
||||
await conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS data.vehicles (
|
||||
id SERIAL PRIMARY KEY,
|
||||
model_id INTEGER REFERENCES ref.vehicle_models(id),
|
||||
vin VARCHAR(50) UNIQUE NOT NULL, -- ALVÁZSZÁM (Az igazi kulcs)
|
||||
current_plate VARCHAR(20) NOT NULL, -- A mostani rendszám
|
||||
production_year INTEGER,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
"""))
|
||||
|
||||
# 3. ÉLETÚT ÉS JOGOSULTSÁG (A Történelem)
|
||||
print("📜 History tábla létrehozása (Kié mikor volt?)...")
|
||||
await conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS data.vehicle_history (
|
||||
id SERIAL PRIMARY KEY,
|
||||
vehicle_id INTEGER REFERENCES data.vehicles(id),
|
||||
user_id INTEGER REFERENCES data.users(id),
|
||||
|
||||
role VARCHAR(20) NOT NULL, -- 'OWNER' (Tulaj), 'DRIVER' (Sofőr), 'LEASE' (Lízingelő)
|
||||
|
||||
start_date DATE NOT NULL, -- Mikor vette át?
|
||||
end_date DATE, -- Mikor adta le? (Ha NULL, akkor nála van!)
|
||||
|
||||
start_mileage INTEGER, -- Óraállás átvételkor
|
||||
end_mileage INTEGER, -- Óraállás leadáskor
|
||||
|
||||
is_active BOOLEAN GENERATED ALWAYS AS (end_date IS NULL) STORED -- Segédmező a gyors kereséshez
|
||||
);
|
||||
"""))
|
||||
|
||||
# 4. KÖLTSÉGEK (Szeparált pénzügyek)
|
||||
print("💸 Costs tábla létrehozása...")
|
||||
await conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS data.costs (
|
||||
id SERIAL PRIMARY KEY,
|
||||
vehicle_id INTEGER REFERENCES data.vehicles(id),
|
||||
user_id INTEGER REFERENCES data.users(id), -- Ki fizette? (Csak ő láthatja!)
|
||||
|
||||
cost_type VARCHAR(50) NOT NULL, -- FUEL, SERVICE, TAX, INSURANCE, LEASE...
|
||||
amount DECIMAL(10, 2) NOT NULL,
|
||||
date DATE NOT NULL,
|
||||
mileage_at_cost INTEGER,
|
||||
|
||||
description TEXT,
|
||||
document_url VARCHAR(255), -- Fotó linkje
|
||||
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
"""))
|
||||
|
||||
print("✅ KÉSZ! A Professzionális Adatmodell felépült.")
|
||||
await engine.dispose()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(build_db())
|
||||
51
archive/2026.02.18 Archive_old_mapps/_legacy_backup/check_garage.py
Executable file
51
archive/2026.02.18 Archive_old_mapps/_legacy_backup/check_garage.py
Executable file
@@ -0,0 +1,51 @@
|
||||
import asyncio
|
||||
import os
|
||||
from sqlalchemy.ext.asyncio import create_async_engine
|
||||
from sqlalchemy import text
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
# DB Config
|
||||
raw_url = os.getenv("DATABASE_URL")
|
||||
if not raw_url:
|
||||
raw_url = "postgresql://admin:PASSWORD_111@postgres-db:5432/service_finder"
|
||||
DATABASE_URL = raw_url.replace("postgresql://", "postgresql+asyncpg://").replace("/service_finder_db", "/service_finder")
|
||||
|
||||
async def check_data():
|
||||
engine = create_async_engine(DATABASE_URL)
|
||||
async with engine.begin() as conn:
|
||||
print("\n🚗 A TE GARÁZSOD (User ID: 1):")
|
||||
print("-" * 80)
|
||||
|
||||
# Ez a lekérdezés összeköti a Történelmet (History), a Vasat (Vehicle) és a Katalógust (Model)
|
||||
query = text("""
|
||||
SELECT
|
||||
vh.role,
|
||||
vh.start_date,
|
||||
v.vin,
|
||||
v.current_plate,
|
||||
m.name as brand,
|
||||
mo.model_name
|
||||
FROM data.vehicle_history vh
|
||||
JOIN data.vehicles v ON vh.vehicle_id = v.id
|
||||
JOIN ref.vehicle_models mo ON v.model_id = mo.id
|
||||
JOIN ref.vehicle_makes m ON mo.make_id = m.id
|
||||
WHERE vh.user_id = 1;
|
||||
""")
|
||||
|
||||
result = await conn.execute(query)
|
||||
rows = result.fetchall()
|
||||
|
||||
if not rows:
|
||||
print("📭 A garázs üres.")
|
||||
else:
|
||||
for r in rows:
|
||||
print(f"🔹 {r.brand} {r.model_name} | 🆔 {r.vin} | 🔢 {r.current_plate}")
|
||||
print(f" Jogviszony: {r.role} | Kezdete: {r.start_date}")
|
||||
print("-" * 80)
|
||||
|
||||
await engine.dispose()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(check_data())
|
||||
35
archive/2026.02.18 Archive_old_mapps/_legacy_backup/create_demo_user.py
Executable file
35
archive/2026.02.18 Archive_old_mapps/_legacy_backup/create_demo_user.py
Executable file
@@ -0,0 +1,35 @@
|
||||
import asyncio
|
||||
import os
|
||||
from sqlalchemy.ext.asyncio import create_async_engine
|
||||
from sqlalchemy import text
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
# Adatbázis elérés
|
||||
raw_url = os.getenv("DATABASE_URL")
|
||||
if not raw_url:
|
||||
raw_url = "postgresql://admin:PASSWORD_111@postgres-db:5432/service_finder"
|
||||
DATABASE_URL = raw_url.replace("postgresql://", "postgresql+asyncpg://").replace("/service_finder_db", "/service_finder")
|
||||
|
||||
async def create_user():
|
||||
print(f"🔌 Kapcsolódás...")
|
||||
engine = create_async_engine(DATABASE_URL)
|
||||
|
||||
async with engine.begin() as conn:
|
||||
print("👤 1-es számú felhasználó beszúrása...")
|
||||
# Kényszerítjük az ID=1-et, hogy passzoljon a main.py-hoz
|
||||
await conn.execute(text("""
|
||||
INSERT INTO data.users (id, email, password_hash, role, is_active)
|
||||
VALUES (1, 'demo@user.com', 'dummy_hash', 'PRIVATE', TRUE)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
"""))
|
||||
|
||||
# Frissítjük a számlálót, hogy a következő user ID 2 legyen (ne akadjon össze)
|
||||
await conn.execute(text("SELECT setval('data.users_id_seq', (SELECT MAX(id) FROM data.users));"))
|
||||
|
||||
print("✅ KÉSZ! A Demo User (ID: 1) létezik.")
|
||||
await engine.dispose()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(create_user())
|
||||
42
archive/2026.02.18 Archive_old_mapps/_legacy_backup/create_dummy_employee.py
Executable file
42
archive/2026.02.18 Archive_old_mapps/_legacy_backup/create_dummy_employee.py
Executable file
@@ -0,0 +1,42 @@
|
||||
import asyncio
|
||||
import os
|
||||
from sqlalchemy.ext.asyncio import create_async_engine
|
||||
from sqlalchemy import text
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
raw_url = os.getenv("DATABASE_URL")
|
||||
if not raw_url:
|
||||
raw_url = "postgresql://admin:PASSWORD_111@postgres-db:5432/service_finder"
|
||||
DATABASE_URL = raw_url.replace("postgresql://", "postgresql+asyncpg://").replace("/service_finder_db", "/service_finder")
|
||||
|
||||
async def hire_driver():
|
||||
engine = create_async_engine(DATABASE_URL)
|
||||
|
||||
async with engine.begin() as conn:
|
||||
print("👤 Kovács János (User ID: 2) létrehozása...")
|
||||
# Létrehozzuk a User-t
|
||||
await conn.execute(text("""
|
||||
INSERT INTO data.users (id, email, password_hash, role, country, default_currency, is_active)
|
||||
VALUES (2, 'sofor@ceg.hu', 'hash123', 'PRIVATE', 'HU', 'HUF', TRUE)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
"""))
|
||||
|
||||
# Frissítjük a sorrendet
|
||||
await conn.execute(text("SELECT setval('data.users_id_seq', (SELECT MAX(id) FROM data.users));"))
|
||||
|
||||
print("🤝 Hozzárendelés a Te cégedhez (ID: 1)...")
|
||||
# Betesszük a fleet_members táblába
|
||||
await conn.execute(text("""
|
||||
INSERT INTO data.fleet_members (user_id, owner_id, role)
|
||||
VALUES (2, 1, 'DRIVER')
|
||||
ON CONFLICT (user_id, owner_id) DO NOTHING;
|
||||
"""))
|
||||
|
||||
print("✅ KÉSZ! Kovács János mostantól a csapatod tagja.")
|
||||
await engine.dispose()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(hire_driver())
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
services:
|
||||
service_finder_api:
|
||||
build: .
|
||||
container_name: service_finder_api
|
||||
env_file:
|
||||
- .env
|
||||
networks:
|
||||
- existing_net
|
||||
ports:
|
||||
- "8000:8000"
|
||||
restart: unless-stopped
|
||||
|
||||
networks:
|
||||
existing_net:
|
||||
external: true
|
||||
name: docker-server_internal_net
|
||||
|
||||
81
archive/2026.02.18 Archive_old_mapps/_legacy_backup/init_db.py
Executable file
81
archive/2026.02.18 Archive_old_mapps/_legacy_backup/init_db.py
Executable file
@@ -0,0 +1,81 @@
|
||||
import asyncio
|
||||
import os
|
||||
from sqlalchemy.ext.asyncio import create_async_engine
|
||||
from sqlalchemy import text
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
# Cím összeállítása (Ugyanaz a logika, mint a main.py-ban)
|
||||
raw_url = os.getenv("DATABASE_URL")
|
||||
if not raw_url:
|
||||
raw_url = "postgresql://admin:PASSWORD_111@postgres-db:5432/service_finder"
|
||||
DATABASE_URL = raw_url.replace("postgresql://", "postgresql+asyncpg://").replace("/service_finder_db", "/service_finder")
|
||||
|
||||
async def init_db():
|
||||
print(f"🔌 Kapcsolódás ide: {DATABASE_URL}")
|
||||
engine = create_async_engine(DATABASE_URL)
|
||||
|
||||
async with engine.begin() as conn:
|
||||
print("🏗️ Séma és Táblák létrehozása...")
|
||||
|
||||
# 1. Séma létrehozása
|
||||
await conn.execute(text("CREATE SCHEMA IF NOT EXISTS ref;"))
|
||||
|
||||
# 2. Márka tábla
|
||||
await conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS ref.vehicle_makes (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(100) NOT NULL UNIQUE
|
||||
);
|
||||
"""))
|
||||
|
||||
# 3. Modell tábla
|
||||
await conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS ref.vehicle_models (
|
||||
id SERIAL PRIMARY KEY,
|
||||
make_id INTEGER REFERENCES ref.vehicle_makes(id),
|
||||
model_name VARCHAR(100) NOT NULL,
|
||||
category VARCHAR(50)
|
||||
);
|
||||
"""))
|
||||
|
||||
print("🧹 Meglévő adatok törlése (Tiszta lap)...")
|
||||
await conn.execute(text("TRUNCATE TABLE ref.vehicle_models, ref.vehicle_makes RESTART IDENTITY CASCADE;"))
|
||||
|
||||
print("🚗 Adatok beszúrása...")
|
||||
|
||||
# Adatok
|
||||
makes = ["BMW", "Audi", "Mercedes-Benz", "Toyota", "Honda", "Suzuki", "Volkswagen"]
|
||||
|
||||
models = [
|
||||
("BMW", "3 Series", "Autó"), ("BMW", "5 Series", "Autó"), ("BMW", "X5", "Autó"), ("BMW", "R 1250 GS", "Motor"),
|
||||
("Audi", "A3", "Autó"), ("Audi", "A4", "Autó"), ("Audi", "A6", "Autó"), ("Audi", "Q5", "Autó"),
|
||||
("Mercedes-Benz", "C-Class", "Autó"), ("Mercedes-Benz", "E-Class", "Autó"), ("Mercedes-Benz", "S-Class", "Autó"), ("Mercedes-Benz", "G-Class", "Autó"),
|
||||
("Toyota", "Corolla", "Autó"), ("Toyota", "Yaris", "Autó"), ("Toyota", "RAV4", "Autó"), ("Toyota", "Hilux", "Autó"),
|
||||
("Honda", "Civic", "Autó"), ("Honda", "CR-V", "Autó"), ("Honda", "Africa Twin", "Motor"), ("Honda", "CB500X", "Motor"),
|
||||
("Suzuki", "Swift", "Autó"), ("Suzuki", "Vitara", "Autó"), ("Suzuki", "S-Cross", "Autó"), ("Suzuki", "DL 650 V-Strom", "Motor"),
|
||||
("Volkswagen", "Golf", "Autó"), ("Volkswagen", "Passat", "Autó"), ("Volkswagen", "Polo", "Autó"), ("Volkswagen", "Tiguan", "Autó")
|
||||
]
|
||||
|
||||
# Márkák beszúrása
|
||||
for make in makes:
|
||||
await conn.execute(text(f"INSERT INTO ref.vehicle_makes (name) VALUES ('{make}') ON CONFLICT DO NOTHING;"))
|
||||
|
||||
# Modellek beszúrása (kicsit trükkös, mert kell a make_id)
|
||||
for brand, model, cat in models:
|
||||
# Megkeressük az ID-t
|
||||
result = await conn.execute(text(f"SELECT id FROM ref.vehicle_makes WHERE name = '{brand}'"))
|
||||
make_id = result.scalar()
|
||||
|
||||
# Beszúrjuk a modellt
|
||||
await conn.execute(text(f"""
|
||||
INSERT INTO ref.vehicle_models (make_id, model_name, category)
|
||||
VALUES ({make_id}, '{model}', '{cat}')
|
||||
"""))
|
||||
|
||||
print("✅ KÉSZ! Az adatbázis feltöltve.")
|
||||
await engine.dispose()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(init_db())
|
||||
61
archive/2026.02.18 Archive_old_mapps/_legacy_backup/inspect_db.py
Executable file
61
archive/2026.02.18 Archive_old_mapps/_legacy_backup/inspect_db.py
Executable file
@@ -0,0 +1,61 @@
|
||||
import asyncio
|
||||
import os
|
||||
from sqlalchemy.ext.asyncio import create_async_engine
|
||||
from sqlalchemy import text
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
# Cím beállítása
|
||||
raw_url = os.getenv("DATABASE_URL")
|
||||
if not raw_url:
|
||||
raw_url = "postgresql://admin:PASSWORD_111@postgres-db:5432/service_finder"
|
||||
DATABASE_URL = raw_url.replace("postgresql://", "postgresql+asyncpg://").replace("/service_finder_db", "/service_finder")
|
||||
|
||||
async def inspect_schema():
|
||||
print(f"🔎 Kapcsolódás az adatbázishoz...")
|
||||
engine = create_async_engine(DATABASE_URL)
|
||||
|
||||
async with engine.begin() as conn:
|
||||
# SQL lekérdezés a rendszer katalógusból (information_schema)
|
||||
# Ez megmondja milyen táblák és oszlopok léteznek
|
||||
query = text("""
|
||||
SELECT
|
||||
table_schema,
|
||||
table_name,
|
||||
column_name,
|
||||
data_type,
|
||||
is_nullable
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema IN ('public', 'ref', 'data')
|
||||
ORDER BY table_schema, table_name, ordinal_position;
|
||||
""")
|
||||
|
||||
result = await conn.execute(query)
|
||||
rows = result.fetchall()
|
||||
|
||||
if not rows:
|
||||
print("⚠️ Nem találtam táblákat a 'ref' vagy 'data' sémákban!")
|
||||
|
||||
current_table = ""
|
||||
for row in rows:
|
||||
schema = row.table_schema
|
||||
table = row.table_name
|
||||
full_table_name = f"{schema}.{table}"
|
||||
|
||||
# Ha új táblához érünk, kiírjuk a nevét
|
||||
if full_table_name != current_table:
|
||||
print(f"\n📦 TÁBLA: {full_table_name.upper()}")
|
||||
print("-" * 50)
|
||||
print(f"{'OSZLOP NÉV':<20} | {'TÍPUS':<15} | {'KÖTELEZŐ?'}")
|
||||
print("-" * 50)
|
||||
current_table = full_table_name
|
||||
|
||||
# Oszlop adatok
|
||||
req = "IGEN" if row.is_nullable == 'NO' else "nem"
|
||||
print(f"{row.column_name:<20} | {row.data_type:<15} | {req}")
|
||||
|
||||
await engine.dispose()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(inspect_schema())
|
||||
69
archive/2026.02.18 Archive_old_mapps/_legacy_backup/inspect_db_full.py
Executable file
69
archive/2026.02.18 Archive_old_mapps/_legacy_backup/inspect_db_full.py
Executable file
@@ -0,0 +1,69 @@
|
||||
import asyncio
|
||||
from sqlalchemy import inspect, text
|
||||
from sqlalchemy.ext.asyncio import create_async_engine
|
||||
|
||||
# CSERÉLD KI a saját adataidra, ha nem ezeket használod!
|
||||
DATABASE_URL = "postgresql+asyncpg://kincses:MiskociA74@postgres-db:5432/service_finder"
|
||||
|
||||
async def run_inspection():
|
||||
# Aszinkron motor létrehozása
|
||||
engine = create_async_engine(DATABASE_URL)
|
||||
|
||||
async with engine.connect() as conn:
|
||||
def do_inspect(sync_conn):
|
||||
inspector = inspect(sync_conn)
|
||||
|
||||
# 1. Sémák lekérése (amiket mi hoztunk létre + public)
|
||||
target_schemas = ['public', 'data', 'ref']
|
||||
all_schemas = inspector.get_schema_names()
|
||||
schemas_to_check = [s for s in target_schemas if s in all_schemas]
|
||||
|
||||
print(f"{'='*60}")
|
||||
print(f" JÁRMŰNYILVÁNTARTÓ RENDSZER - ADATBÁZIS AUDIT")
|
||||
print(f"{'='*60}")
|
||||
|
||||
for schema in schemas_to_check:
|
||||
print(f"\n--- SÉMA: {schema.upper()} ---")
|
||||
tables = inspector.get_table_names(schema=schema)
|
||||
|
||||
if not tables:
|
||||
print(" (Nincsenek táblák ebben a sémában)")
|
||||
continue
|
||||
|
||||
for table_name in tables:
|
||||
print(f"\n[Tábla: {schema}.{table_name}]")
|
||||
|
||||
# Oszlopok részletei
|
||||
columns = inspector.get_columns(table_name, schema=schema)
|
||||
for col in columns:
|
||||
pk = " [PK]" if col['primary_key'] else ""
|
||||
nullable = "NULL" if col['nullable'] else "NOT NULL"
|
||||
print(f" L {col['name']:<15} | {str(col['type']):<12} | {nullable}{pk}")
|
||||
|
||||
# Idegen kulcsok (Kapcsolatok)
|
||||
fks = inspector.get_foreign_keys(table_name, schema=schema)
|
||||
for fk in fks:
|
||||
constrained = fk['constrained_columns']
|
||||
referred_schema = fk['referred_schema']
|
||||
referred_table = fk['referred_table']
|
||||
referred_cols = fk['referred_columns']
|
||||
print(f" --> Kapcsolat: {constrained} -> {referred_schema}.{referred_table}({referred_cols})")
|
||||
|
||||
# Mivel az SQLAlchemy inspector alapvetően szinkron, run_sync-et használunk
|
||||
await conn.run_sync(do_inspect)
|
||||
|
||||
# 2. Extra: Kiterjesztések ellenőrzése
|
||||
print(f"\n{'='*60}")
|
||||
print(" AKTÍV POSTGRESQL KITERJESZTÉSEK:")
|
||||
result = await conn.execute(text("SELECT extname FROM pg_extension;"))
|
||||
for row in result:
|
||||
print(f" - {row[0]}")
|
||||
print(f"{'='*60}")
|
||||
|
||||
await engine.dispose()
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
asyncio.run(run_inspection())
|
||||
except Exception as e:
|
||||
print(f"HIBA TÖRTÉNT: {e}")
|
||||
81
archive/2026.02.18 Archive_old_mapps/_legacy_backup/main.py
Executable file
81
archive/2026.02.18 Archive_old_mapps/_legacy_backup/main.py
Executable file
@@ -0,0 +1,81 @@
|
||||
from fastapi import FastAPI, HTTPException, Form, Depends
|
||||
from fastapi.responses import FileResponse, JSONResponse
|
||||
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy import text
|
||||
from datetime import datetime, timedelta, date
|
||||
from jose import jwt
|
||||
import bcrypt, os, traceback
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
SECRET_KEY = "SZUPER_TITKOS_KULCS_2026"
|
||||
ALGORITHM = "HS256"
|
||||
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="api/auth/login")
|
||||
DATABASE_URL = os.getenv("DATABASE_URL", "").replace("postgresql://", "postgresql+asyncpg://")
|
||||
engine = create_async_engine(DATABASE_URL, pool_pre_ping=True)
|
||||
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
# --- AUTH ---
|
||||
def get_password_hash(p): return bcrypt.hashpw(p.encode('utf-8')[:72], bcrypt.gensalt()).decode('utf-8')
|
||||
def verify_password(p, h): return bcrypt.checkpw(p.encode('utf-8')[:72], h.encode('utf-8'))
|
||||
|
||||
async def get_current_user(token: str = Depends(oauth2_scheme)):
|
||||
try:
|
||||
p = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
|
||||
return int(p.get("sub"))
|
||||
except: raise HTTPException(status_code=401)
|
||||
|
||||
@app.post("/api/auth/register")
|
||||
async def register(email: str = Form(...), password: str = Form(...)):
|
||||
try:
|
||||
async with AsyncSessionLocal() as session:
|
||||
async with session.begin():
|
||||
await session.execute(text("INSERT INTO data.users (email, password_hash) VALUES (:e, :p)"),
|
||||
{"e": email, "p": get_password_hash(password)})
|
||||
return {"status": "success"}
|
||||
except Exception as e:
|
||||
return JSONResponse(status_code=400, content={"detail": "Email már létezik vagy adatbázis hiba."})
|
||||
|
||||
@app.post("/api/auth/login")
|
||||
async def login(f: OAuth2PasswordRequestForm = Depends()):
|
||||
async with AsyncSessionLocal() as session:
|
||||
res = await session.execute(text("SELECT id, password_hash FROM data.users WHERE email = :e"), {"e": f.username})
|
||||
u = res.fetchone()
|
||||
if not u or not verify_password(f.password, u.password_hash): raise HTTPException(status_code=401, detail="Hibás adatok")
|
||||
t = jwt.encode({"sub": str(u.id), "exp": datetime.utcnow() + timedelta(days=1)}, SECRET_KEY, algorithm=ALGORITHM)
|
||||
return {"access_token": t, "token_type": "bearer"}
|
||||
|
||||
# --- DATA ---
|
||||
@app.get("/api/meta/vehicle-hierarchy")
|
||||
async def get_hierarchy():
|
||||
async with AsyncSessionLocal() as session:
|
||||
q = text("SELECT vm.category, m.name as brand, vm.id as model_id, vm.model_name FROM ref.vehicle_models vm JOIN ref.vehicle_makes m ON vm.make_id = m.id ORDER BY vm.category, m.name")
|
||||
res = await session.execute(q)
|
||||
h = {}
|
||||
for r in res:
|
||||
if r.category not in h: h[r.category] = {}
|
||||
if r.brand not in h[r.category]: h[r.category][r.brand] = []
|
||||
h[r.category][r.brand].append({"id": r.model_id, "name": r.model_name})
|
||||
return h
|
||||
|
||||
@app.get("/api/meta/cost-types")
|
||||
async def get_cost_types():
|
||||
async with AsyncSessionLocal() as session:
|
||||
res = await session.execute(text("SELECT code, name FROM ref.cost_types ORDER BY name"))
|
||||
return {r.code: r.name for r in res.fetchall()}
|
||||
|
||||
@app.get("/api/my_vehicles")
|
||||
async def my_vehicles(uid: int = Depends(get_current_user)):
|
||||
async with AsyncSessionLocal() as session:
|
||||
q = text("SELECT v.id as vehicle_id, v.current_plate as plate, m.name as brand, mo.model_name as model, v.status FROM data.vehicle_history vh JOIN data.vehicles v ON vh.vehicle_id = v.id JOIN ref.vehicle_models mo ON v.model_id = mo.id JOIN ref.vehicle_makes m ON mo.make_id = m.id WHERE vh.user_id = :uid AND vh.end_date IS NULL")
|
||||
res = await session.execute(q, {"uid": uid})
|
||||
return [dict(r._mapping) for r in res.fetchall()]
|
||||
|
||||
@app.get("/")
|
||||
async def index(): return FileResponse("/app/frontend/index.html")
|
||||
120
archive/2026.02.18 Archive_old_mapps/_legacy_backup/main_2.py
Executable file
120
archive/2026.02.18 Archive_old_mapps/_legacy_backup/main_2.py
Executable file
@@ -0,0 +1,120 @@
|
||||
from fastapi import FastAPI, HTTPException
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from fastapi.responses import FileResponse
|
||||
from pydantic import BaseModel, validator
|
||||
from typing import Optional
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy import text
|
||||
import os
|
||||
from datetime import date
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
# --- 1. ADATBÁZIS KAPCSOLAT ---
|
||||
raw_url = os.getenv("DATABASE_URL")
|
||||
if not raw_url:
|
||||
raw_url = "postgresql://admin:PASSWORD_111@postgres-db:5432/service_finder"
|
||||
fixed_url = raw_url.replace("postgresql://", "postgresql+asyncpg://").replace("/service_finder_db", "/service_finder")
|
||||
|
||||
engine = create_async_engine(fixed_url)
|
||||
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||
|
||||
app = FastAPI(title="Service Finder API")
|
||||
|
||||
# --- 2. ADATMODELLEK (VALIDÁCIÓVAL) ---
|
||||
class VehicleRegister(BaseModel):
|
||||
model_id: int
|
||||
vin: str # Alvázszám (KÖTELEZŐ!)
|
||||
plate: str # Rendszám
|
||||
mileage: int # Km óra
|
||||
purchase_date: date
|
||||
role: str = "OWNER" # Alapértelmezett: Tulajdonos
|
||||
|
||||
# Adatőr: Automatikus nagybetűsítés és tisztítás
|
||||
@validator('vin')
|
||||
def clean_vin(cls, v):
|
||||
if len(v) < 5: raise ValueError('Az alvázszám túl rövid!')
|
||||
return v.upper().replace("-", "").replace(" ", "")
|
||||
|
||||
@validator('plate')
|
||||
def clean_plate(cls, v):
|
||||
return v.upper().replace("-", "").replace(" ", "")
|
||||
|
||||
@validator('mileage')
|
||||
def positive_mileage(cls, v):
|
||||
if v < 0: raise ValueError('A kilométer nem lehet negatív!')
|
||||
return v
|
||||
|
||||
# --- 3. VÉGPONTOK ---
|
||||
|
||||
# Lista lekérése (Katalógus)
|
||||
@app.get("/api/vehicles")
|
||||
async def get_vehicles():
|
||||
async with AsyncSessionLocal() as session:
|
||||
result = await session.execute(text("""
|
||||
SELECT vm.id, m.name as brand, vm.model_name, vm.category
|
||||
FROM ref.vehicle_models vm
|
||||
JOIN ref.vehicle_makes m ON vm.make_id = m.id
|
||||
ORDER BY m.name, vm.model_name
|
||||
"""))
|
||||
return [{"id": r.id, "brand": r.brand, "model": r.model_name, "category": r.category} for r in result.fetchall()]
|
||||
|
||||
# ÚJ: JÁRMŰ REGISZTRÁCIÓ (A Nagy Logika)
|
||||
@app.post("/api/register")
|
||||
async def register_vehicle(data: VehicleRegister):
|
||||
async with AsyncSessionLocal() as session:
|
||||
async with session.begin(): # Tranzakció indítása
|
||||
try:
|
||||
# 1. Megnézzük, létezik-e már ez a VAS (Alvázszám alapján)?
|
||||
check_query = text("SELECT id FROM data.vehicles WHERE vin = :vin")
|
||||
result = await session.execute(check_query, {"vin": data.vin})
|
||||
existing_car_id = result.scalar()
|
||||
|
||||
vehicle_id = existing_car_id
|
||||
|
||||
# 2. HA NEM LÉTEZIK -> Létrehozzuk a VASAT
|
||||
if not vehicle_id:
|
||||
print(f"🆕 Új autó az adatbázisban: {data.vin}")
|
||||
insert_car = text("""
|
||||
INSERT INTO data.vehicles (model_id, vin, current_plate)
|
||||
VALUES (:mid, :vin, :plt)
|
||||
RETURNING id
|
||||
""")
|
||||
res = await session.execute(insert_car, {
|
||||
"mid": data.model_id, "vin": data.vin, "plt": data.plate
|
||||
})
|
||||
vehicle_id = res.scalar()
|
||||
else:
|
||||
print(f"♻️ Létező autó átvétele: {data.vin} (ID: {vehicle_id})")
|
||||
# Itt később lezárhatjuk az előző tulajdonos history-ját!
|
||||
|
||||
# 3. BEJEGYZÉS A TÖRTÉNELEMBE (HISTORY)
|
||||
# Ez köti össze a User-t (most fixen ID=1) az Autóval
|
||||
insert_history = text("""
|
||||
INSERT INTO data.vehicle_history
|
||||
(vehicle_id, user_id, role, start_date, start_mileage)
|
||||
VALUES (:vid, 1, :role, :s_date, :s_mil)
|
||||
""")
|
||||
|
||||
await session.execute(insert_history, {
|
||||
"vid": vehicle_id,
|
||||
"role": data.role,
|
||||
"s_date": data.purchase_date,
|
||||
"s_mil": data.mileage
|
||||
})
|
||||
|
||||
return {"status": "success", "message": "Jármű sikeresen rögzítve a flottában!"}
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Hiba: {e}")
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
# Frontend kiszolgálása
|
||||
@app.get("/")
|
||||
async def serve_frontend():
|
||||
if os.path.exists("/app/frontend/index.html"):
|
||||
return FileResponse("/app/frontend/index.html")
|
||||
return {"error": "Frontend hiányzik"}
|
||||
|
||||
49
archive/2026.02.18 Archive_old_mapps/_legacy_backup/main_final.py
Executable file
49
archive/2026.02.18 Archive_old_mapps/_legacy_backup/main_final.py
Executable file
@@ -0,0 +1,49 @@
|
||||
from fastapi import FastAPI
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy import text
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
app = FastAPI(title="Service Finder API")
|
||||
|
||||
# --- A DUPLA JAVÍTÁS ---
|
||||
raw_url = os.getenv("DATABASE_URL")
|
||||
|
||||
if not raw_url:
|
||||
# Vészhelyzeti fallback (ha nem lenne .env)
|
||||
raw_url = "postgresql://admin:PASSWORD_111@postgres-db:5432/service_finder"
|
||||
|
||||
# 1. Javítás: Driver csere (asyncpg)
|
||||
fixed_url = raw_url.replace("postgresql://", "postgresql+asyncpg://")
|
||||
|
||||
# 2. Javítás: Adatbázis név csere (Ha véletlenül _db a vége, levágjuk)
|
||||
fixed_url = fixed_url.replace("/service_finder_db", "/service_finder")
|
||||
|
||||
print(f"🔧 VÉGLEGES ADATBÁZIS CÍM: {fixed_url}")
|
||||
|
||||
# Kapcsolódás a javított címmel
|
||||
engine = create_async_engine(fixed_url)
|
||||
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||
|
||||
@app.get("/")
|
||||
async def root():
|
||||
return {"message": "Service Finder API működik! 🚀"}
|
||||
|
||||
@app.get("/vehicles")
|
||||
async def get_vehicles():
|
||||
async with AsyncSessionLocal() as session:
|
||||
try:
|
||||
query = text("""
|
||||
SELECT m.name as brand, vm.model_name, vm.category
|
||||
FROM ref.vehicle_models vm
|
||||
JOIN ref.vehicle_makes m ON vm.make_id = m.id
|
||||
ORDER BY m.name, vm.model_name
|
||||
""")
|
||||
result = await session.execute(query)
|
||||
vehicles = result.fetchall()
|
||||
return [{"brand": r.brand, "model": r.model_name, "category": r.category} for r in vehicles]
|
||||
except Exception as e:
|
||||
return {"error": str(e)}
|
||||
52
archive/2026.02.18 Archive_old_mapps/_legacy_backup/main_fixed.py
Executable file
52
archive/2026.02.18 Archive_old_mapps/_legacy_backup/main_fixed.py
Executable file
@@ -0,0 +1,52 @@
|
||||
from fastapi import FastAPI
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy import text
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Betöltjük a környezeti változókat
|
||||
load_dotenv()
|
||||
|
||||
app = FastAPI(title="Service Finder API")
|
||||
|
||||
# --- A FIX ---
|
||||
# Kiolvassuk a címet
|
||||
raw_url = os.getenv("DATABASE_URL")
|
||||
|
||||
# Ha nincs beállítva, adunk egy vészhelyzeti alapértelmezettet
|
||||
if not raw_url:
|
||||
print("⚠️ FIGYELEM: Nincs DATABASE_URL, alapértelmezett használata!")
|
||||
# Itt a konténer belső nevét (postgres-db) használjuk
|
||||
raw_url = "postgresql://admin:MiskociA74@postgres-db:5432/service_finder"
|
||||
|
||||
# A LÉNYEG: Ha hiányzik az '+asyncpg', hozzáadjuk!
|
||||
if "asyncpg" not in raw_url:
|
||||
DATABASE_URL = raw_url.replace("postgresql://", "postgresql+asyncpg://")
|
||||
print(f"🔧 URL javítva erre: {DATABASE_URL}")
|
||||
else:
|
||||
DATABASE_URL = raw_url
|
||||
|
||||
# Motor indítása a javított URL-lel
|
||||
engine = create_async_engine(DATABASE_URL)
|
||||
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||
|
||||
@app.get("/")
|
||||
async def root():
|
||||
return {"message": "Service Finder API működik! 🚀"}
|
||||
|
||||
@app.get("/vehicles")
|
||||
async def get_vehicles():
|
||||
async with AsyncSessionLocal() as session:
|
||||
try:
|
||||
query = text("""
|
||||
SELECT m.name as brand, vm.model_name, vm.category
|
||||
FROM ref.vehicle_models vm
|
||||
JOIN ref.vehicle_makes m ON vm.make_id = m.id
|
||||
ORDER BY m.name, vm.model_name
|
||||
""")
|
||||
result = await session.execute(query)
|
||||
vehicles = result.fetchall()
|
||||
return [{"brand": r.brand, "model": r.model_name, "category": r.category} for r in vehicles]
|
||||
except Exception as e:
|
||||
return {"error": str(e)}
|
||||
71
archive/2026.02.18 Archive_old_mapps/_legacy_backup/migrate_ref_data.py
Executable file
71
archive/2026.02.18 Archive_old_mapps/_legacy_backup/migrate_ref_data.py
Executable file
@@ -0,0 +1,71 @@
|
||||
import asyncio
|
||||
import os
|
||||
from sqlalchemy.ext.asyncio import create_async_engine
|
||||
from sqlalchemy import text
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
raw_url = os.getenv("DATABASE_URL")
|
||||
if not raw_url:
|
||||
raw_url = "postgresql://admin:PASSWORD_111@postgres-db:5432/service_finder"
|
||||
DATABASE_URL = raw_url.replace("postgresql://", "postgresql+asyncpg://").replace("/service_finder_db", "/service_finder")
|
||||
|
||||
async def seed_cost_types():
|
||||
engine = create_async_engine(DATABASE_URL)
|
||||
async with engine.begin() as conn:
|
||||
print("🔨 Költség típusok tábla létrehozása...")
|
||||
await conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS ref.cost_types (
|
||||
code VARCHAR(50) PRIMARY KEY,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
parent_code VARCHAR(50) REFERENCES ref.cost_types(code), -- Hierarchia!
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
sort_order INTEGER DEFAULT 0
|
||||
);
|
||||
"""))
|
||||
|
||||
print("📥 Adatok feltöltése...")
|
||||
# Először a szülők (Főkategóriák)
|
||||
parents = [
|
||||
('FUEL', '⛽ Tankolás', 10),
|
||||
('PURCHASE', '💰 Beszerzés / Pénzügy', 20),
|
||||
('INSURANCE', '📄 Biztosítás', 30),
|
||||
('TAX', '🏛️ Adó / Illeték', 40),
|
||||
('SERVICE', '🔧 Szerviz', 50),
|
||||
('OTHER', 'Egyéb', 99)
|
||||
]
|
||||
for p in parents:
|
||||
await conn.execute(text("INSERT INTO ref.cost_types (code, name, sort_order) VALUES (:c, :n, :s) ON CONFLICT (code) DO NOTHING"), {"c": p[0], "n": p[1], "s": p[2]})
|
||||
|
||||
# Aztán a gyerekek (Alkategóriák)
|
||||
children = [
|
||||
# Beszerzés
|
||||
('PURCHASE_PRICE', 'Vételár', 'PURCHASE'),
|
||||
('FINANCE_LEASE', 'Lízing díj', 'PURCHASE'),
|
||||
('FINANCE_LOAN', 'Hitel törlesztő', 'PURCHASE'),
|
||||
('IMPORT_FEE', 'Honosítás / Regadó', 'PURCHASE'),
|
||||
# Biztosítás
|
||||
('INSURANCE_KGFB', 'Kötelező (KGFB)', 'INSURANCE'),
|
||||
('INSURANCE_CASCO', 'Casco', 'INSURANCE'),
|
||||
('INSURANCE_GAP', 'GAP', 'INSURANCE'),
|
||||
('INSURANCE_ASSIST', 'Assistance', 'INSURANCE'),
|
||||
# Adó
|
||||
('TAX_WEIGHT', 'Gépjárműadó (Súlyadó)', 'TAX'),
|
||||
('TAX_COMPANY', 'Cégautóadó', 'TAX'),
|
||||
('TAX_TRANSFER', 'Vagyonszerzési illeték', 'TAX'),
|
||||
('TAX_OTHER', 'Egyéb adó', 'TAX'),
|
||||
# Szerviz
|
||||
('SERVICE_MAINTENANCE', 'Kötelező karbantartás', 'SERVICE'),
|
||||
('SERVICE_REPAIR', 'Javítás', 'SERVICE'),
|
||||
('SERVICE_TIRE', 'Gumicsere', 'SERVICE'),
|
||||
('SERVICE_MOT', 'Műszaki vizsga', 'SERVICE')
|
||||
]
|
||||
for c in children:
|
||||
await conn.execute(text("INSERT INTO ref.cost_types (code, name, parent_code) VALUES (:c, :n, :p) ON CONFLICT (code) DO NOTHING"), {"c": c[0], "n": c[1], "p": c[2]})
|
||||
|
||||
print("✅ KÉSZ! A tudás most már az adatbázisban van, nem a HTML-ben.")
|
||||
await engine.dispose()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(seed_cost_types())
|
||||
0
archive/2026.02.18 Archive_old_mapps/_legacy_backup/teszt.txt
Executable file
0
archive/2026.02.18 Archive_old_mapps/_legacy_backup/teszt.txt
Executable file
46
archive/2026.02.18 Archive_old_mapps/_legacy_backup/update_audit_system.py
Executable file
46
archive/2026.02.18 Archive_old_mapps/_legacy_backup/update_audit_system.py
Executable file
@@ -0,0 +1,46 @@
|
||||
import asyncio
|
||||
import os
|
||||
from sqlalchemy.ext.asyncio import create_async_engine
|
||||
from sqlalchemy import text
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
raw_url = os.getenv("DATABASE_URL")
|
||||
if not raw_url:
|
||||
raw_url = "postgresql://admin:PASSWORD_111@postgres-db:5432/service_finder"
|
||||
DATABASE_URL = raw_url.replace("postgresql://", "postgresql+asyncpg://").replace("/service_finder_db", "/service_finder")
|
||||
|
||||
async def build_audit_system():
|
||||
engine = create_async_engine(DATABASE_URL)
|
||||
|
||||
async with engine.begin() as conn:
|
||||
print("📜 Audit Log tábla létrehozása...")
|
||||
# Ez a tábla sosem töröl, csak ír! (Append-only)
|
||||
await conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS data.audit_logs (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER REFERENCES data.users(id), -- KI csinálta?
|
||||
event_type VARCHAR(50) NOT NULL, -- MIT? (pl. ISSUE_REPORT, MILEAGE_UPDATE)
|
||||
target_id INTEGER, -- MELYIK autón? (Vehicle ID)
|
||||
old_value TEXT, -- MI volt előtte? (A visszaállításhoz)
|
||||
new_value TEXT, -- MI lett utána?
|
||||
details TEXT, -- Egyéb megjegyzés (pl. hiba leírása)
|
||||
ip_address VARCHAR(45), -- Honnan? (Biztonság)
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
"""))
|
||||
|
||||
print("🚦 Jármű Státusz mezők hozzáadása...")
|
||||
# Bővítjük a járműveket, hogy tárolják a hibát
|
||||
await conn.execute(text("""
|
||||
ALTER TABLE data.vehicles
|
||||
ADD COLUMN IF NOT EXISTS status VARCHAR(20) DEFAULT 'OK', -- OK, WARNING, CRITICAL
|
||||
ADD COLUMN IF NOT EXISTS current_issue TEXT; -- A hiba leírása
|
||||
"""))
|
||||
|
||||
print("✅ KÉSZ! A mindent látó szem (Audit Log) aktív.")
|
||||
await engine.dispose()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(build_audit_system())
|
||||
@@ -0,0 +1,56 @@
|
||||
import asyncio
|
||||
import os
|
||||
from sqlalchemy.ext.asyncio import create_async_engine
|
||||
from sqlalchemy import text
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
raw_url = os.getenv("DATABASE_URL")
|
||||
if not raw_url:
|
||||
raw_url = "postgresql://admin:PASSWORD_111@postgres-db:5432/service_finder"
|
||||
DATABASE_URL = raw_url.replace("postgresql://", "postgresql+asyncpg://").replace("/service_finder_db", "/service_finder")
|
||||
|
||||
async def expand_categories():
|
||||
engine = create_async_engine(DATABASE_URL)
|
||||
async with engine.begin() as conn:
|
||||
print("📥 Új Főkategóriák beszúrása...")
|
||||
parents = [
|
||||
('EQUIPMENT', '🛠️ Felszerelés / Extrák', 25), # Vételár után
|
||||
('OPERATIONAL', '🅿️ Üzemeltetés / Út', 15), # Tankolás után
|
||||
('FINE', '👮 Bírság / Büntetés', 90)
|
||||
]
|
||||
for p in parents:
|
||||
await conn.execute(text("INSERT INTO ref.cost_types (code, name, sort_order) VALUES (:c, :n, :s) ON CONFLICT (code) DO NOTHING"), {"c": p[0], "n": p[1], "s": p[2]})
|
||||
|
||||
print("📥 Új Alkategóriák beszúrása...")
|
||||
children = [
|
||||
# Felszerelés (EQUIPMENT)
|
||||
('EQUIP_SHELVING', 'Raktérburkolat / Polcrendszer', 'EQUIPMENT'),
|
||||
('EQUIP_BRANDING', 'Matricázás / Fóliázás', 'EQUIPMENT'),
|
||||
('EQUIP_TOWBAR', 'Vonóhorog / Tetőcsomagtartó', 'EQUIPMENT'),
|
||||
('EQUIP_SAFETY', 'Kötelező tartozékok (Eü. csomag)', 'EQUIPMENT'),
|
||||
('EQUIP_GPS', 'GPS / Nyomkövető hardver', 'EQUIPMENT'),
|
||||
('EQUIP_WINTER_TIRE', 'Téli gumi szett (Beszerzés)', 'EQUIPMENT'),
|
||||
|
||||
# Üzemeltetés (OPERATIONAL)
|
||||
('OP_PARKING', 'Parkolás', 'OPERATIONAL'),
|
||||
('OP_TOLL', 'Útdíj / Matrica / Behajtás', 'OPERATIONAL'),
|
||||
('OP_WASH', 'Mosás / Kozmetika', 'OPERATIONAL'),
|
||||
('OP_ADBLUE', 'AdBlue', 'OPERATIONAL'),
|
||||
('OP_EV_CHARGE', 'Elektromos töltés', 'OPERATIONAL'),
|
||||
('OP_STORAGE', 'Gumi hotel / Tárolás', 'OPERATIONAL'),
|
||||
|
||||
# Bírság (FINE)
|
||||
('FINE_SPEEDING', 'Gyorshajtás', 'FINE'),
|
||||
('FINE_PARKING', 'Parkolási bírság', 'FINE'),
|
||||
('FINE_ADMIN', 'Közigazgatási bírság', 'FINE')
|
||||
]
|
||||
for c in children:
|
||||
await conn.execute(text("INSERT INTO ref.cost_types (code, name, parent_code) VALUES (:c, :n, :p) ON CONFLICT (code) DO NOTHING"), {"c": c[0], "n": c[1], "p": c[2]})
|
||||
|
||||
print("✅ KÉSZ! A költséglista most már teljeskörű.")
|
||||
await engine.dispose()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(expand_categories())
|
||||
46
archive/2026.02.18 Archive_old_mapps/_legacy_backup/update_db_i18n.py
Executable file
46
archive/2026.02.18 Archive_old_mapps/_legacy_backup/update_db_i18n.py
Executable file
@@ -0,0 +1,46 @@
|
||||
import asyncio
|
||||
import os
|
||||
from sqlalchemy.ext.asyncio import create_async_engine
|
||||
from sqlalchemy import text
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
raw_url = os.getenv("DATABASE_URL")
|
||||
if not raw_url:
|
||||
raw_url = "postgresql://admin:PASSWORD_111@postgres-db:5432/service_finder"
|
||||
DATABASE_URL = raw_url.replace("postgresql://", "postgresql+asyncpg://").replace("/service_finder_db", "/service_finder")
|
||||
|
||||
async def upgrade_db():
|
||||
print(f"🔌 Kapcsolódás...")
|
||||
engine = create_async_engine(DATABASE_URL)
|
||||
|
||||
async with engine.begin() as conn:
|
||||
print("🌍 Felhasználói tábla bővítése (Ország + Alapértelmezett pénznem)...")
|
||||
# 1. Users tábla bővítése
|
||||
await conn.execute(text("""
|
||||
ALTER TABLE data.users
|
||||
ADD COLUMN IF NOT EXISTS country VARCHAR(2) DEFAULT 'HU',
|
||||
ADD COLUMN IF NOT EXISTS default_currency VARCHAR(3) DEFAULT 'HUF';
|
||||
"""))
|
||||
|
||||
print("💶 Költség tábla bővítése (Tranzakciós pénznem)...")
|
||||
# 2. Costs tábla bővítése
|
||||
await conn.execute(text("""
|
||||
ALTER TABLE data.costs
|
||||
ADD COLUMN IF NOT EXISTS currency VARCHAR(3) DEFAULT 'HUF';
|
||||
"""))
|
||||
|
||||
# Frissítjük a meglévő Demo Usert (ID=1)
|
||||
print("👤 Demo User beállítása: Magyarország / HUF")
|
||||
await conn.execute(text("""
|
||||
UPDATE data.users
|
||||
SET country = 'HU', default_currency = 'HUF'
|
||||
WHERE id = 1;
|
||||
"""))
|
||||
|
||||
print("✅ KÉSZ! Az adatbázis mostantól támogatja a több pénznemet.")
|
||||
await engine.dispose()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(upgrade_db())
|
||||
26
archive/2026.02.18 Archive_old_mapps/_legacy_backup/update_docs.py
Executable file
26
archive/2026.02.18 Archive_old_mapps/_legacy_backup/update_docs.py
Executable file
@@ -0,0 +1,26 @@
|
||||
import asyncio
|
||||
import os
|
||||
from sqlalchemy.ext.asyncio import create_async_engine
|
||||
from sqlalchemy import text
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
raw_url = os.getenv("DATABASE_URL")
|
||||
if not raw_url:
|
||||
raw_url = "postgresql://admin:PASSWORD_111@postgres-db:5432/service_finder"
|
||||
DATABASE_URL = raw_url.replace("postgresql://", "postgresql+asyncpg://").replace("/service_finder_db", "/service_finder")
|
||||
|
||||
async def add_doc_column():
|
||||
engine = create_async_engine(DATABASE_URL)
|
||||
async with engine.begin() as conn:
|
||||
print("📄 Dokumentum oszlop hozzáadása a Costs táblához...")
|
||||
await conn.execute(text("""
|
||||
ALTER TABLE data.costs
|
||||
ADD COLUMN IF NOT EXISTS document_url VARCHAR(255);
|
||||
"""))
|
||||
print("✅ KÉSZ! Mehetnek a fájlok.")
|
||||
await engine.dispose()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(add_doc_column())
|
||||
58
archive/2026.02.18 Archive_old_mapps/_legacy_backup/update_invitations.py
Executable file
58
archive/2026.02.18 Archive_old_mapps/_legacy_backup/update_invitations.py
Executable file
@@ -0,0 +1,58 @@
|
||||
import asyncio
|
||||
import os
|
||||
from sqlalchemy.ext.asyncio import create_async_engine
|
||||
from sqlalchemy import text
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
raw_url = os.getenv("DATABASE_URL")
|
||||
if not raw_url:
|
||||
raw_url = "postgresql://admin:PASSWORD_111@postgres-db:5432/service_finder"
|
||||
DATABASE_URL = raw_url.replace("postgresql://", "postgresql+asyncpg://").replace("/service_finder_db", "/service_finder")
|
||||
|
||||
async def upgrade_invites():
|
||||
print(f"🔌 Kapcsolódás...")
|
||||
engine = create_async_engine(DATABASE_URL)
|
||||
|
||||
async with engine.begin() as conn:
|
||||
print("📨 Invitations (Meghívók) tábla létrehozása...")
|
||||
# Ez tárolja a függőben lévő meghívásokat
|
||||
await conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS data.invitations (
|
||||
id SERIAL PRIMARY KEY,
|
||||
email VARCHAR(255) NOT NULL,
|
||||
inviter_id INTEGER REFERENCES data.users(id), -- Ki hívta meg? (Cég)
|
||||
role VARCHAR(20) NOT NULL, -- Milyen szerepre? (MANAGER, DRIVER)
|
||||
access_level VARCHAR(20) DEFAULT 'FULL', -- A/B Sofőr szint
|
||||
token VARCHAR(100) UNIQUE NOT NULL, -- A titkos link kódja
|
||||
status VARCHAR(20) DEFAULT 'PENDING', -- PENDING, ACCEPTED, EXPIRED
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
expires_at TIMESTAMP
|
||||
);
|
||||
"""))
|
||||
|
||||
print("🤝 Fleet Members (Többcéges tagság) tábla létrehozása...")
|
||||
# Ez teszi lehetővé, hogy valaki több céghez is tartozzon
|
||||
await conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS data.fleet_members (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER REFERENCES data.users(id), -- A Dolgozó
|
||||
owner_id INTEGER REFERENCES data.users(id), -- A Cég / Tulajdonos
|
||||
role VARCHAR(20) NOT NULL, -- FLEET_MANAGER, DRIVER
|
||||
joined_at TIMESTAMP DEFAULT NOW(),
|
||||
|
||||
-- Egy ember egy cégnél csak egyszer szerepelhet
|
||||
UNIQUE(user_id, owner_id)
|
||||
);
|
||||
"""))
|
||||
|
||||
# Takarítás: A régi 'parent_id' már nem kell, mert a fleet_members kiváltja
|
||||
# De biztonságból egyelőre csak NULL-ra állítjuk, nem töröljük az oszlopot
|
||||
# await conn.execute(text("UPDATE data.users SET parent_id = NULL;"))
|
||||
|
||||
print("✅ KÉSZ! A rendszer készen áll a biztonságos meghívókra.")
|
||||
await engine.dispose()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(upgrade_invites())
|
||||
61
archive/2026.02.18 Archive_old_mapps/_legacy_backup/update_permissions.py
Executable file
61
archive/2026.02.18 Archive_old_mapps/_legacy_backup/update_permissions.py
Executable file
@@ -0,0 +1,61 @@
|
||||
import asyncio
|
||||
import os
|
||||
from sqlalchemy.ext.asyncio import create_async_engine
|
||||
from sqlalchemy import text
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
raw_url = os.getenv("DATABASE_URL")
|
||||
if not raw_url:
|
||||
raw_url = "postgresql://admin:PASSWORD_111@postgres-db:5432/service_finder"
|
||||
DATABASE_URL = raw_url.replace("postgresql://", "postgresql+asyncpg://").replace("/service_finder_db", "/service_finder")
|
||||
|
||||
async def upgrade_permissions():
|
||||
print(f"🔌 Kapcsolódás...")
|
||||
engine = create_async_engine(DATABASE_URL)
|
||||
|
||||
async with engine.begin() as conn:
|
||||
print("👑 USERS tábla bővítése (Rendszer és Szervezeti szintek)...")
|
||||
|
||||
# 1. SYS_ROLE: Rendszergazda / Moderátor / User
|
||||
await conn.execute(text("""
|
||||
ALTER TABLE data.users
|
||||
ADD COLUMN IF NOT EXISTS sys_role VARCHAR(20) DEFAULT 'USER';
|
||||
"""))
|
||||
|
||||
# 2. HIERARCHIA: Ki a főnököd? (Parent User ID)
|
||||
# Ha NULL, akkor ő a Cégtulajdonos (SuperUser). Ha van ID, akkor Alkalmazott.
|
||||
await conn.execute(text("""
|
||||
ALTER TABLE data.users
|
||||
ADD COLUMN IF NOT EXISTS parent_id INTEGER REFERENCES data.users(id);
|
||||
"""))
|
||||
|
||||
# 3. ORG_ROLE: Cégen belüli szerep (Owner, Fleet Manager, Employee)
|
||||
await conn.execute(text("""
|
||||
ALTER TABLE data.users
|
||||
ADD COLUMN IF NOT EXISTS org_role VARCHAR(20) DEFAULT 'OWNER';
|
||||
"""))
|
||||
|
||||
print("🚦 VEHICLE_HISTORY tábla bővítése (Sofőr jogosultságok)...")
|
||||
|
||||
# 4. ACCESS_LEVEL: Mit láthat a sofőr? (COST_MANAGER vs LOG_ONLY)
|
||||
await conn.execute(text("""
|
||||
ALTER TABLE data.vehicle_history
|
||||
ADD COLUMN IF NOT EXISTS access_level VARCHAR(20) DEFAULT 'FULL';
|
||||
-- Lehetséges értékek: 'FULL', 'COST_MANAGER', 'LOG_ONLY'
|
||||
"""))
|
||||
|
||||
# --- DEMO ADATOK FRISSÍTÉSE ---
|
||||
print("👤 Demo User (ID:1) kinevezése Rendszergazdának és Cégtulajdonosnak...")
|
||||
await conn.execute(text("""
|
||||
UPDATE data.users
|
||||
SET sys_role = 'SYS_ADMIN', org_role = 'OWNER', parent_id = NULL
|
||||
WHERE id = 1;
|
||||
"""))
|
||||
|
||||
print("✅ KÉSZ! A jogosultsági mátrix beépítve az adatbázisba.")
|
||||
await engine.dispose()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(upgrade_permissions())
|
||||
Reference in New Issue
Block a user