Key Data Models in Project N.O.M.A.D.'s Database: Complete Schema Guide
Project N.O.M.A.D. persists its operational state across nine core AdonisJS Lucid models—Service, WikipediaSelection, KVStore, InstalledResource, CollectionManifest, ChatSession, ChatMessage, BenchmarkSetting, and BenchmarkResult—that manage Docker microservices, content installations, LLM conversations, and hardware benchmarking data.
Project N.O.M.A.D. (Nomad Operating Machine-Assisted Data-store) is an open-source platform that orchestrates offline-capable services through Docker-based microservices. The application layer stores all operational state, user content selections, and system metrics in a relational database accessed through AdonisJS Lucid ORM models located in admin/app/models. Understanding these key data models used in Project N.O.M.A.D.'s database is essential for developers extending the platform or integrating with its API.
Service Model: Managing Docker Microservice Dependencies
The Service model (defined in admin/app/models/service.ts) represents every containerized microservice that Nomad can install or manage.
Self-Referential Dependency Graphs
This model implements a dependency tree through self-referential relationships. The dependency field establishes a belongsTo relationship to another Service, while dependencies provides a hasMany inverse. This allows Nomad to resolve installation order when services rely on others (e.g., a database container required by an application).
Key Service Attributes
Notable columns include service_name, container_image, installed (boolean flag), ui_location (where the service UI is exposed), and metadata (JSON configuration). When a user enables a service, the installed flag transitions to true and available_update_version may populate if updates exist.
// Fetch installed services with their dependency chains
import Service from '#models/service'
const services = await Service.query()
.where('installed', true)
.preload('dependencies')
Content Management Models: ZIM Files and Map Resources
Project N.O.M.A.D. manages offline content through three interconnected models that track downloadable resources.
WikipediaSelection
The WikipediaSelection model (admin/app/models/wikipedia_selection.ts) tracks the lifecycle of Wikipedia ZIM files selected for download. Key fields include option_id (unique identifier), url (source location), filename, and status—which follows a state machine of none, downloading, installed, or failed.
import WikipediaSelection from '#models/wikipedia_selection'
const selection = await WikipediaSelection.findBy('option_id', 'enwiki-20240101')
if (selection) {
selection.status = 'installed'
await selection.save()
}
InstalledResource
Once downloaded, physical files are recorded in InstalledResource (admin/app/models/installed_resource.ts). This model distinguishes between resource types via the resource_type enum (zim or map), storing file_path, version, and installed_at timestamps. It bridges the gap between logical selections and actual filesystem assets.
CollectionManifest
To avoid repeated network requests, CollectionManifest (admin/app/models/collection_manifest.ts) caches remote catalog metadata. The type field (typed as ManifestType), spec_version, and spec_data (JSON blob) store Kiwix or map catalog information with fetched_at timestamps for cache invalidation.
Configuration Storage: The KVStore Model
For application settings that don't warrant dedicated tables, the KVStore model (admin/app/models/kv_store.ts) provides a type-safe key-value interface. The key field adheres to KV_STORE_SCHEMA for type safety, while value stores stringified data.
Static helper methods simplify access:
import KVStore from '#models/kv_store'
await KVStore.setValue('ui_theme', 'dark')
const theme = await KVStore.getValue('ui_theme') // Returns 'dark'
This pattern supports UI preferences, API keys, and feature flags without schema migrations.
Conversational AI: ChatSession and ChatMessage
The platform's built-in LLM assistant persists conversations through two related models.
ChatSession
ChatSession (admin/app/models/chat_session.ts) represents a top-level conversation, storing title and the model identifier (e.g., 'llama.cpp'). It maintains a hasMany relationship to individual messages.
ChatMessage
ChatMessage (admin/app/models/chat_message.ts) contains the actual conversation content with role enums (system, user, assistant) and content text. The session_id foreign key establishes the belongsTo relationship back to the parent session.
import ChatSession from '#models/chat_session'
import ChatMessage from '#models/chat_message'
const session = await ChatSession.create({
title: 'Nomad Help',
model: 'llama.cpp'
})
await ChatMessage.create({
session_id: session.id,
role: 'user',
content: 'How do I add a new map?'
})
Performance Benchmarking: BenchmarkSetting and BenchmarkResult
The "NOMAD Score" feature relies on two models that configure and store hardware performance metrics.
BenchmarkSetting
BenchmarkSetting (admin/app/models/benchmark_setting.ts) stores configuration values for the benchmark subsystem. The key field uses the BenchmarkSettingKey enum (e.g., controlling anonymous submission preferences), with corresponding value storage.
BenchmarkResult
BenchmarkResult (admin/app/models/benchmark_result.ts) persists comprehensive performance data including cpu_score, memory_score, disk_read_score, disk_write_score, and ai_tokens_per_second. The composite nomad_score aggregates these metrics into a single performance rating, while submitted_to_repository tracks whether results were shared upstream.
import BenchmarkResult from '#models/benchmark_result'
await BenchmarkResult.create({
benchmark_id: 'run-2024-03-01',
benchmark_type: 'hardware',
cpu_model: 'Intel i7-12700K',
cpu_cores: 12,
ram_bytes: 32_000_000_000,
disk_type: 'ssd',
cpu_score: 8450,
memory_score: 7200,
disk_read_score: 1500,
nomad_score: 88,
submitted_to_repository: false,
})
Common Model Architecture
All models inherit from BaseModel and utilize SnakeCaseNamingStrategy, ensuring database columns use snake_case (e.g., created_at, updated_at). Timestamps are automatically managed via the @column.dateTime({ autoCreate: true, autoUpdate: true }) decorator, eliminating manual date handling.
Summary
- Service models manage Docker microservices with self-referential dependency graphs for installation ordering.
- WikipediaSelection and InstalledResource track the lifecycle of offline content from download queue to filesystem storage.
- CollectionManifest caches remote catalog metadata to minimize network requests.
- KVStore provides type-safe key-value storage for miscellaneous application settings.
- ChatSession and ChatMessage implement conversational logging for the LLM assistant.
- BenchmarkSetting and BenchmarkResult support the NOMAD Score feature with detailed hardware and AI performance metrics.
- All models reside in
admin/app/modelsand leverage AdonisJS Lucid ORM conventions with automatic timestamp management.
Frequently Asked Questions
What ORM does Project N.O.M.A.D. use for its database models?
Project N.O.M.A.D. uses AdonisJS Lucid, an ActiveRecord-style ORM that provides the BaseModel class inherited by all data models. This ORM handles query building, relationships, and timestamp management automatically.
How does the Service model handle dependencies between Docker containers?
The Service model implements self-referential relationships through belongsTo (dependency) and hasMany (dependencies) associations defined in admin/app/models/service.ts. This allows the system to resolve installation order by traversing the dependency graph before starting containers.
Where are the database models located in the Project N.O.M.A.D. repository?
All TypeScript model files are located in the admin/app/models/ directory, with each model typically named after its entity (e.g., service.ts, kv_store.ts, benchmark_result.ts). They follow AdonisJS conventions using snake_case database columns via SnakeCaseNamingStrategy.
What is the difference between WikipediaSelection and InstalledResource?
WikipediaSelection tracks the user's intent to download specific ZIM files and manages download states (downloading, installed, etc.), while InstalledResource records the actual physical files present on the host system, including file paths and versions for both ZIM and map resources.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →