Scaffold project, data model and artwork

Establish the LLeMbas foundation: FastAPI/Jinja/SQLite layout, the ORM
schema, and the original SVG identity.

Notable decisions, all recorded in comments at the point they matter:

- No Alembic. SQLite only, schema created at startup, so models carry a
  few columns nothing reads yet (Message.parent_id for branching,
  content_parts_json for multimodal turns). Adding them later to a live
  database without migrations is the painful path.
- Sessions are server-side rows keyed by a SHA-256 of the cookie value,
  not JWTs, so logout and bans revoke access immediately.
- Upstream API keys are Fernet-encrypted with a key derived from
  LEMBAS_SECRET_KEY. decrypt() fails soft to "" so rotating the secret
  degrades to re-entering keys rather than crashing the admin UI.
- Artwork is generated by scripts/build_artwork.py rather than hand-drawn
  per file: the mallorn leaf appears in the icon, favicon, lockup and
  banner, and one source is the only way those stay in sync. The wordmark
  is Source Serif 4 (OFL) converted to outlines, because a README banner
  cannot load a webfont and <text> would render in whatever serif the
  viewer happens to have.
- Icons live in a template partial, not assets/, because same-document
  <use href="#id"> is universally supported and the cross-document form
  is not.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jaroslav Beneš
2026-07-21 10:34:48 +02:00
parent 0665027bc6
commit 5ef2af6a9f
32 changed files with 2041 additions and 0 deletions
+34
View File
@@ -0,0 +1,34 @@
# LLeMbas configuration
# Copy to .env and edit. All variables are prefixed LEMBAS_.
# REQUIRED. Secret used to sign session cookies and to derive the key that
# encrypts stored API keys at rest. Generate one with:
# python -c "import secrets; print(secrets.token_urlsafe(48))"
# Changing this invalidates all sessions AND makes stored API keys unreadable.
LEMBAS_SECRET_KEY=
# Where the SQLite database and uploaded files live.
LEMBAS_DATA_DIR=./data
# HTTP server bind address.
LEMBAS_HOST=127.0.0.1
LEMBAS_PORT=8080
# Autoreload on code change. Development only.
LEMBAS_RELOAD=false
# debug | info | warning | error
LEMBAS_LOG_LEVEL=info
# Allow new accounts to register themselves. The very first account created is
# always an admin, regardless of this setting. Turn off once your users exist.
LEMBAS_ALLOW_SIGNUP=true
# Default theme for signed-out visitors: moria (dark) or shire (light).
LEMBAS_DEFAULT_THEME=moria
# Seconds a login session stays valid. Default 30 days.
LEMBAS_SESSION_TTL=2592000
# Seconds to wait on an upstream LLM endpoint before giving up.
LEMBAS_REQUEST_TIMEOUT=300