@exulu/backend source. For what each method does and how to structure your initdb script, see Configuration.
Import
ExuluDatabase is a plain object — not a class instance. There is nothing to construct.
ExuluDatabase.init()
All
ExuluContext instances registered in this application. IMP creates the items table (and chunks table when the context has an embedder) for any context whose tables do not yet exist.When
true, also calls initLitellmDb() to push the LiteLLM proxy schema to the database at LITELLM_DATABASE_URL. Pass false to skip.init() does on every call:
- Runs
up(db)— creates or alters the ~26 core application tables. - Calls
contextDatabases(contexts)— creates missing items and chunks tables for each context. - Inserts the
adminrole if absent. - Inserts the
defaultrole if absent. - Inserts the default admin user (
admin@exulu.com) if absent. - Calls
generateApiKey("exulu", "api@exulu.com")and logs the result. The key is persisted only if noapi@exulu.comuser exists (first boot). See persistence semantics. - Optionally calls
initLitellmDb().
ExuluDatabase.update()
init(). Identical behaviour. Use when adding contexts or upgrading an existing installation to make the intent explicit.
ExuluDatabase.api.key.generate()
Human-readable identifier for this API key. Used as the
name column on the API user record and as the sanitized postfix in the key string: sk_…/sanitized_name (lowercased, spaces replaced with underscores).Email address for the API user record. Trimmed and lowercased before use. Used as the lookup key — if a user with this email already exists, the new key is returned but not persisted (see persistence semantics below).
The generated plain-text API key. Format:
sk_{random}_{random}/{sanitized_name}. Example: sk_9x7h3j2k5l8_4m6n1p9q8r/my_app_api.Key format
The returned key has three parts:
The database stores
{bcrypt_hash(plain_key)}/{sanitized_name} in the apikey column. The hash uses 12 bcrypt salt rounds. IMP’s authentication middleware extracts the postfix suffix to find the user record before verifying the hash.
Persistence semantics
email exists is stored and will authenticate. Keys returned for existing users are discarded and will fail authentication.
Example
Generating multiple keys
To provision keys for different services, use different email addresses:The first-boot key
ExuluDatabase.init() calls generateApiKey("exulu", "api@exulu.com") internally on every run and logs the result:
ExuluDatabase.api.key.generate() explicitly after init() in your initdb script — that key is tied to your email address and will not conflict with the default api@exulu.com entry.
Context table helpers
These methods are called byExuluDatabase.init() internally via ExuluContext. You rarely need to invoke them directly; they are listed here for completeness and are documented on the ExuluContext API reference page.
Next steps
Configuration
Options for
init() / update(), the LiteLLM flag, and the complete initdb example.Self-hosting — database
The no-migration model, first-boot bootstrap, and database backup strategy.