Skip to content

Latest commit

 

History

23 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SFF Backend

A FastAPI backend for user accounts and text logs this was specifically made for a roblox game i was working on where I wanted our developers to post logs from a studio plugin!

NOTE: currently account creation is being restrained by a header token being needed, i dont want any joe shmoe from adding a user to the db

What This Project Uses

  • FastAPI for the HTTP API surface
  • SQLAlchemy ORM with SQLite storage
  • Pydantic for request validation at the API boundary
  • msgspec Structs for service/core contracts
  • JWT bearer tokens for authentication

Documentation Sources (Homework Citations)

Project Layout

  • src/main.py: app entrypoint for Uvicorn
  • src/app.py: FastAPI app factory and router registration
  • src/db/session.py: engine/session/Base and DB dependency
  • src/models/: SQLAlchemy models
  • src/schemas/: API request schemas (Pydantic)
  • src/schemas/core/: service/core contracts (msgspec)
  • src/repo/: data access layer
  • src/services/: business logic layer
  • src/security/: password hashing and JWT helpers
  • src/api/routers/: HTTP routes
  • src/util/response.py: unified response pipeline

Response Envelope

All endpoints return a consistent envelope:

  • code: status code label, for example SUCCESS, NOT_FOUND, ALREADY_EXISTS
  • detail: human-readable summary
  • result: payload object/list/null

Example success:

{
  "code": "SUCCESS",
  "detail": "User retrieved successfully",
  "result": {
    "id": 1,
    "username": "camey",
    "created_at": "2026-04-13T20:40:11.123456"
  }
}

Example error:

{
  "code": "ALREADY_EXISTS",
  "detail": "Username camey already exists",
  "result": null
}

Authentication Flow

  1. Register a user with POST /api/users/ and header X-User-Creation-Token
  2. Login with POST /api/users/login to receive access_token
  3. Send token in Authorization header:
Authorization: Bearer <access_token>
  1. Access protected routes such as /api/logs/ and /api/users/{id}

API Endpoints

Users

  • POST /api/users/ (requires X-User-Creation-Token): create account
  • POST /api/users/login (public): login and receive bearer token
  • GET /api/users/{user_id} (auth): get own user
  • PATCH /api/users/{user_id} (auth): modify own user
  • DELETE /api/users/{user_id} (auth): delete own user

Logs

  • GET /api/logs/ (auth): list logs (supports optional user_id, offset, limit query params)
  • GET /api/logs/{log_id} (auth): get one owned log
  • POST /api/logs/ (auth): create log (optional created_at override)
  • PATCH /api/logs/{log_id} (auth): modify owned log
  • WS /api/logs/ws?token= (auth): subscribe to log.created events

Quick Start

1) Install dependencies

pip install -r requirements.txt

2) Required environment variables

  • JWT_SECRET
  • USER_CREATION_TOKEN

3) Optional environment variables

  • DATABASE_URL (default: sqlite:///./sff.db)
  • JWT_EXPIRE_MINUTES (default: 60)

Codespaces note:

  • Store JWT_SECRET and USER_CREATION_TOKEN as Codespaces secrets.
  • They are exposed as environment variables at runtime, so no dotenv file is required.

PowerShell example:

$env:JWT_SECRET = "super-secret-value"
$env:USER_CREATION_TOKEN = "long-random-create-token"
$env:JWT_EXPIRE_MINUTES = "120"

4) Run the API

uvicorn src.main:app --reload

5) Open docs

Request Examples

Create user:

curl -X POST http://127.0.0.1:8000/api/users/ \
  -H "X-User-Creation-Token: YOUR_CREATE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"username":"camey","password":"securePass123"}'

Login:

curl -X POST http://127.0.0.1:8000/api/users/login \
  -H "Content-Type: application/json" \
  -d '{"username":"camey","password":"securePass123"}'

Create log with server timestamp (replace TOKEN):

curl -X POST http://127.0.0.1:8000/api/logs/ \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"message":"first log entry"}'

Create log with timezone-aware timestamp override:

curl -X POST http://127.0.0.1:8000/api/logs/ \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"message":"logged from mobile","created_at":"2026-04-13T21:42:00-05:00"}'

Notes for created_at override:

  • Field is optional.
  • Must include a timezone offset (for example Z or -05:00).
  • Server preserves the submitted wall-clock timestamp when an override is provided.

Subscribe to realtime log events via WebSocket:

ws://127.0.0.1:8000/api/logs/ws?token=<access_token>

Notes

  • Tables are auto-created at startup through Base.metadata.create_all(...)
  • Passwords are stored as PBKDF2-SHA256 hashes, never plaintext.

About

A developer note repo and endpoint handler for working on a specific roblox game, paired with a Roblox extension

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages