Features: - Add LinkedIn OAuth integration and auto-posting functionality - Add scheduler service for automated post publishing - Add metadata field to generated_posts for LinkedIn URLs - Add privacy policy page for LinkedIn API compliance - Add company management features and employee accounts - Add license key system for company registrations Fixes: - Fix timezone issues (use UTC consistently across app) - Fix datetime serialization errors in database operations - Fix scheduling timezone conversion (local time to UTC) - Fix import errors (get_database -> db) Infrastructure: - Update Docker setup to use port 8001 (avoid conflicts) - Add SSL support with nginx-proxy and Let's Encrypt - Add LinkedIn setup documentation - Add migration scripts for schema updates Services: - Add linkedin_service.py for LinkedIn API integration - Add scheduler_service.py for background job processing - Add storage_service.py for Supabase Storage - Add email_service.py improvements - Add encryption utilities for token storage Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
72 lines
2.0 KiB
Python
72 lines
2.0 KiB
Python
"""FastAPI web frontend for LinkedIn Post Creation System."""
|
|
from contextlib import asynccontextmanager
|
|
from pathlib import Path
|
|
|
|
from fastapi import FastAPI
|
|
from fastapi.staticfiles import StaticFiles
|
|
from fastapi.responses import RedirectResponse
|
|
from loguru import logger
|
|
|
|
from src.config import settings
|
|
from src.web.admin import admin_router
|
|
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(app: FastAPI):
|
|
"""Manage application lifecycle - startup and shutdown."""
|
|
# Startup
|
|
logger.info("Starting LinkedIn Post Creation System...")
|
|
|
|
# Initialize and start scheduler if enabled
|
|
scheduler = None
|
|
if settings.user_frontend_enabled:
|
|
try:
|
|
from src.database.client import DatabaseClient
|
|
from src.services.scheduler_service import init_scheduler
|
|
|
|
db = DatabaseClient()
|
|
scheduler = init_scheduler(db, check_interval=60) # Check every 60 seconds
|
|
await scheduler.start()
|
|
logger.info("Scheduler service started")
|
|
except Exception as e:
|
|
logger.error(f"Failed to start scheduler: {e}")
|
|
|
|
yield # Application runs here
|
|
|
|
# Shutdown
|
|
logger.info("Shutting down LinkedIn Post Creation System...")
|
|
if scheduler:
|
|
await scheduler.stop()
|
|
logger.info("Scheduler service stopped")
|
|
|
|
|
|
# Setup
|
|
app = FastAPI(title="LinkedIn Post Creation System", lifespan=lifespan)
|
|
|
|
# Static files
|
|
app.mount("/static", StaticFiles(directory=Path(__file__).parent / "static"), name="static")
|
|
|
|
# Include admin router (always available)
|
|
app.include_router(admin_router)
|
|
|
|
# Include user router if enabled
|
|
if settings.user_frontend_enabled:
|
|
from src.web.user import user_router
|
|
app.include_router(user_router)
|
|
else:
|
|
# Root redirect only when user frontend is disabled
|
|
@app.get("/")
|
|
async def root():
|
|
"""Redirect root to admin frontend."""
|
|
return RedirectResponse(url="/admin", status_code=302)
|
|
|
|
|
|
def run_web():
|
|
"""Run the web server."""
|
|
import uvicorn
|
|
uvicorn.run(app, host="0.0.0.0", port=8000)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
run_web()
|