11c4810231
Implements docs/planning/social.md US-1's API layer on top of the
merged Friendship/Follow/Block models (app/models/social.py):
- POST/GET /api/friends/requests, POST .../accept, POST .../decline
- DELETE /api/friends/{user_id} (unfriend)
- POST/DELETE /api/friends/{user_id}/follow, GET /api/friends/following
- POST/DELETE /api/friends/{user_id}/block, GET /api/friends/blocked
- GET /api/friends (mutual friends list)
All endpoints require JWT auth. Requests are scoped to caller (no
cross-account enumeration); duplicate/self requests are rejected
idempotently; block clears mutual friendship and follow in both directions.
Independently re-verified: 19/19 new unit/integration tests pass,
239/239 full backend test suite passes with zero regressions.
56 lines
1.8 KiB
Python
56 lines
1.8 KiB
Python
"""FastAPI application entry point."""
|
|
|
|
from contextlib import asynccontextmanager
|
|
|
|
from fastapi import FastAPI
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
|
|
from app.config import settings
|
|
from app.routers import auth, users, worlds, assets, avatar, world_content, internal, presence, groups, social_friends
|
|
|
|
|
|
from app.services.game_servers import supervisor
|
|
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(app: FastAPI):
|
|
"""Application lifespan: startup and shutdown events."""
|
|
supervisor.start()
|
|
yield
|
|
await supervisor.shutdown()
|
|
|
|
|
|
app = FastAPI(
|
|
title=settings.APP_NAME,
|
|
version=settings.APP_VERSION,
|
|
description="Agentic Game Platform - Backend API",
|
|
lifespan=lifespan,
|
|
)
|
|
|
|
# CORS
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=settings.cors_origins_list,
|
|
allow_credentials=True,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
|
|
# Include routers
|
|
app.include_router(auth.router, prefix="/api/auth", tags=["auth"])
|
|
app.include_router(users.router, prefix="/api/users", tags=["users"])
|
|
app.include_router(worlds.router, prefix="/api/worlds", tags=["worlds"])
|
|
app.include_router(world_content.router, prefix="/api/worlds", tags=["world-content"])
|
|
app.include_router(assets.router, prefix="/api/assets", tags=["assets"])
|
|
app.include_router(avatar.router, prefix="/api/avatar", tags=["avatar"])
|
|
app.include_router(internal.router, prefix="/api/internal", tags=["internal"])
|
|
app.include_router(presence.router, prefix="/api/presence", tags=["presence"])
|
|
app.include_router(groups.router, prefix="/api/groups", tags=["groups"])
|
|
app.include_router(social_friends.router, prefix="/api/friends", tags=["friends"])
|
|
|
|
|
|
@app.get("/api/health")
|
|
async def health_check():
|
|
"""Simple health check endpoint."""
|
|
return {"status": "ok", "app": settings.APP_NAME}
|