from dotenv import load_dotenv load_dotenv() from fastapi import FastAPI, Request from fastapi.responses import JSONResponse from pydantic import ValidationError from fastapi.middleware.cors import CORSMiddleware # FastAPI アプリケーション作成 app = FastAPI( title="日本小規模企業向け会計システム" ) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=False, allow_methods=["*"], allow_headers=["*"], ) @app.exception_handler(ValidationError) async def validation_exception_handler(request: Request, exc: ValidationError): # ここでは最初のエラーだけ簡潔に返す(必要に応じて整形) first = exc.errors()[0] msg = first.get("msg", "入力値が不正です。") return JSONResponse(status_code=400, content={"detail": msg}) # ───────────────────────── # ルート(稼働確認) # ───────────────────────── @app.get("/", summary="稼働確認") def root(): return {"status": "ok"} # ───────────────────────── # ルーター登録(※ 必ず app 定義の後) # ───────────────────────── from app.modules.accounts.router import router as accounts_router app.include_router(accounts_router) from app.modules.journals.router import router as journals_router app.include_router(journals_router) from app.modules.ledger.router import router as ledger_router app.include_router(ledger_router) from app.modules.trial_balance.router import router as trial_balance_router app.include_router(trial_balance_router) from app.modules.opening_balances.router import router as opening_router app.include_router(opening_router) from app.modules.general_ledger.router import router as general_ledger_router app.include_router(general_ledger_router) from app.modules.opening_balances.lock_router import router as opening_balance_lock_router app.include_router(opening_balance_lock_router) from app.routers import journal_entries from app.routers import cash from app.routers import accounts app.include_router(journal_entries.router) app.include_router(cash.router) app.include_router(accounts.router) from app.routers import month_locks app.include_router(month_locks.router) from app.routers import year_locks app.include_router(year_locks.router) from app.routers import cash app.include_router(cash.router) from app.routers import file_upload app.include_router(file_upload.router) # ───────────────────────── # 給与モジュール (Payroll Module) # ───────────────────────── from app.payroll.employees.router import router as payroll_employees_router app.include_router(payroll_employees_router) from app.payroll.settings.router import router as payroll_settings_router app.include_router(payroll_settings_router) from app.payroll.settings.standard_remuneration_router import router as standard_remuneration_router app.include_router(standard_remuneration_router) from app.payroll.calculation.router import router as payroll_calculation_router app.include_router(payroll_calculation_router) from app.payroll.bonus.router import router as payroll_bonus_router app.include_router(payroll_bonus_router) from fastapi.staticfiles import StaticFiles import os from pathlib import Path # アップロードファイル用の静的ファイル配信 uploads_dir = Path("uploads") uploads_dir.mkdir(exist_ok=True) app.mount( "/uploads", StaticFiles(directory="uploads"), name="uploads", ) # 静的ファイル配信(コメントアウト - ディレクトリが存在しない) # app.mount( # "/static", # StaticFiles(directory="app/static", html=True), # name="static", # ) # フロントエンドファイル配信 frontend_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "frontend") if os.path.exists(frontend_path): app.mount( "/frontend", StaticFiles(directory=frontend_path, html=True), name="frontend", ) else: print(f"Frontend path not found: {frontend_path}")