Project


|- app
	|- models
		|- __init__.py
		|- base.py
		|- entities.py
		|- enums.py
	|- modules
		|- abuse
			|- service.py
		|- admin
			|- router.py
		|- auth
			|- router.py
		|- communication
			|- handlers.py
			|- sms.py
			|- voice.py
		|- landing
			|- router.py
		|- owner
			|- router.py
		|- tags
			|- router.py
	|- services
		|- auth.py
		|- phone.py
		|- short_id.py
		|- tags.py
		|- validation.py
	|- shared
		|- database.py
		|- deps.py
		|- kafka_client.py
		|- logging.py
		|- redis_client.py
	|- __init__.py
	|- config.py
	|- main.py
|- migrations
	|- versions
	|- en.py
|- scripts
	|- bulk_generate_qr.py
	|- phone_activation_demo.py
|- tests
	|- conftest.py
	|- test_integration.py
	|- test_utils.py
|- alembic.ini
|- requirements.txt
|- ptest.ini
        
Dockerfile
FROM python:3.11-slim
...
COPY backend ./backend
COPY frontend ./frontend
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--app-dir", "backend"]

// Start app.main:app
            

Entry Point
# cat backend/app/main.py
from app.modules.admin.router import router as admin_router
from app.modules.auth.router import router as auth_router
from app.modules.landing.router import router as landing_router
from app.modules.owner.router import router as owner_router
from app.modules.tags.router import router as tags_router

def create_app() -> FastAPI:
    application.include_router(landing_router)
    application.include_router(tags_router)
    application.include_router(auth_router)
    application.include_router(admin_router)
    application.include_router(owner_router)
    return application

app = create_app()
Rest Endpoints Testinghttp://127.0.0.1:8000/docs

backend/app/modules/landing/router.py
/s/{short_id}
/s/{short_id}/chat
/s/{short_id}/call
/activate/{short_id}
@router.get("/s/{short_id}", response_class=HTMLResponse)
async def scan_landing(request: Request, short_id: str, db: AsyncSession = Depends(get_db)):

@router.post("/s/{short_id}/chat", response_class=HTMLResponse)
async def submit_chat()

@router.post("/s/{short_id}/call", response_class=HTMLResponse)
async def submit_call()

@router.get("/activate/{short_id}", response_class=HTMLResponse)
async def activate_start()