Files
evo-sync/web-python/main.py
mguschin 854c912a88 Migrate web app from Python/FastAPI to Node.js/TypeScript
Replace the entire Python/FastAPI backend with a Node.js/TypeScript stack:
- Framework: Hono + @hono/node-server
- Templates: Nunjucks (.njk) replacing Jinja2 (.html)
- ORM: Drizzle ORM with mysql2 (same MariaDB schema, no migrations needed)
- Sessions: hono-sessions with CookieStore
- CSS: Pico CSS v2 replacing Bootstrap 5 (Bootstrap Icons CDN kept)
- Dev: tsx watch; Prod: tsc + node dist/index.js

Original Python app preserved in web-python/ as backup.
Updated Dockerfile.web and docker-compose.yml for Node.js deployment.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 19:33:32 +03:00

54 lines
1.6 KiB
Python

import asyncio
from contextlib import asynccontextmanager
from fastapi import FastAPI, Depends, Request
from fastapi.responses import RedirectResponse
from fastapi.staticfiles import StaticFiles
from starlette.middleware.sessions import SessionMiddleware
from web.auth import get_current_user
from web.config import settings
from web.health_checker import health_check_loop
from web.sync_engine import sync_loop
from web.models import User
from web.routes import auth, profile, reset, evotor, vk, sync, catalog
from web.routes import connections
@asynccontextmanager
async def lifespan(app: FastAPI):
tasks = [
asyncio.create_task(health_check_loop(settings.HEALTH_CHECK_INTERVAL_SECONDS)),
asyncio.create_task(sync_loop(settings.SYNC_INTERVAL_SECONDS)),
]
yield
for t in tasks:
t.cancel()
for t in tasks:
try:
await t
except asyncio.CancelledError:
pass
app = FastAPI(title="ЭВОСИНК — Личный кабинет", lifespan=lifespan)
app.add_middleware(SessionMiddleware, secret_key=settings.SECRET_KEY)
app.mount("/static", StaticFiles(directory="web/static"), name="static")
app.include_router(auth.router)
app.include_router(profile.router)
app.include_router(reset.router)
app.include_router(evotor.router)
app.include_router(connections.router)
app.include_router(vk.router)
app.include_router(sync.router)
app.include_router(catalog.router)
@app.get("/")
def home(request: Request, user: User | None = Depends(get_current_user)):
if user:
return RedirectResponse("/profile", 302)
return RedirectResponse("/login", 302)