- Add BASE_PATH config, include all routers with prefix
- Inject {{ base }} Jinja2 global for all template URLs
- Add window.BASE_PATH for static JS files
- Update Nginx to proxy /careerbot/ path
- Add OPS_MANUAL.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
96 lines
2.9 KiB
Python
96 lines
2.9 KiB
Python
from fastapi import APIRouter, Depends, Request
|
|
from fastapi.responses import HTMLResponse, RedirectResponse
|
|
from fastapi.templating import Jinja2Templates
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.config import settings
|
|
from app.database import get_db
|
|
from app.models import Profile, Skill, Education, WorkExperience, AccessToken
|
|
|
|
BASE = settings.BASE_PATH
|
|
|
|
router = APIRouter()
|
|
templates = Jinja2Templates(directory="templates")
|
|
|
|
|
|
@router.get("/", response_class=HTMLResponse)
|
|
def index_page(request: Request, db: Session = Depends(get_db)):
|
|
token = request.cookies.get("visitor_token")
|
|
if not token:
|
|
return RedirectResponse(url=f"{BASE}/login", status_code=302)
|
|
# Allow both valid tokens and anonymous
|
|
if token != "__anonymous__":
|
|
record = db.query(AccessToken).filter(
|
|
AccessToken.token == token, AccessToken.is_active == True
|
|
).first()
|
|
if not record:
|
|
return RedirectResponse(url=f"{BASE}/login", status_code=302)
|
|
return templates.TemplateResponse(request, "index.html")
|
|
|
|
|
|
@router.get("/login", response_class=HTMLResponse)
|
|
def login_page(request: Request):
|
|
return templates.TemplateResponse(request, "login.html")
|
|
|
|
|
|
@router.get("/api/profile")
|
|
def get_profile(db: Session = Depends(get_db)):
|
|
profile = db.query(Profile).first()
|
|
if not profile:
|
|
return {}
|
|
return {
|
|
"name": profile.name,
|
|
"phone": profile.phone,
|
|
"location": profile.location,
|
|
"birthday": profile.birthday,
|
|
"party": profile.party,
|
|
"education_level": profile.education_level,
|
|
"email": profile.email,
|
|
"photo_url": profile.photo_url,
|
|
"self_summary": profile.self_summary,
|
|
}
|
|
|
|
|
|
@router.get("/api/skills")
|
|
def get_skills(db: Session = Depends(get_db)):
|
|
skills = db.query(Skill).order_by(Skill.sort_order).all()
|
|
return [
|
|
{"id": s.id, "category": s.category, "content": s.content}
|
|
for s in skills
|
|
]
|
|
|
|
|
|
@router.get("/api/education")
|
|
def get_education(db: Session = Depends(get_db)):
|
|
items = db.query(Education).order_by(Education.sort_order).all()
|
|
return [
|
|
{
|
|
"id": e.id,
|
|
"start_date": e.start_date,
|
|
"end_date": e.end_date,
|
|
"school": e.school,
|
|
"major": e.major,
|
|
"degree": e.degree,
|
|
"details": e.details,
|
|
}
|
|
for e in items
|
|
]
|
|
|
|
|
|
@router.get("/api/experience")
|
|
def get_experience(db: Session = Depends(get_db)):
|
|
items = db.query(WorkExperience).order_by(WorkExperience.sort_order).all()
|
|
return [
|
|
{
|
|
"id": exp.id,
|
|
"start_date": exp.start_date,
|
|
"end_date": exp.end_date,
|
|
"company": exp.company,
|
|
"position": exp.position,
|
|
"company_intro": exp.company_intro,
|
|
"responsibilities": exp.responsibilities,
|
|
"achievements": exp.achievements,
|
|
}
|
|
for exp in items
|
|
]
|