Storage Architecture
Relevant source files
The following files were used as context for generating this wiki page:
PRKS manages a local-first research library using a combination of relational databases, on-disk file management, and browser-side persistent caches. The system prioritizes data durability and single-process ownership to ensure library integrity during concurrent access or system failures.
The architecture is currently in transition from a single-user SQLite-based system to a multi-user modular monolith capable of supporting PostgreSQL as a canonical relational store.
Sources: backend/AGENTS.md:6-15, README.md:3-8
Storage Root and Resource Resolution
PRKS uses a designated "storage root" directory to house all persistent library data. A storage root is uniquely identified by a prks-root.json marker file containing a stable storage_root_id. Exactly one PRKS server process may use a storage root at a time, enforced by an operating-system lock on .prks-maintenance/root.lock.
Resolution Hierarchy
The application determines the storage root path at startup following a strict priority order:
- The
--storage-rootcommand-line argument. - The
PRKS_STORAGEenvironment variable. - The
storage.local_rootentry in the bootstrap configuration file. - The default
data/directory within the project repository.
Sources: README.md:104-124, backend/AGENTS.md:58-70, AGENTS.md:435-438
Data Layout
The following table describes the standard layout of a storage root:
| Component | Path | Description |
|---|---|---|
| Canonical Database | prks_data.db | Main SQLite database containing library metadata and structured research data. |
| Managed PDFs | pdfs/ | Directory for all stored PDF documents. |
| PDF Thumbnails | thumbs/ | Derived image cache for PDF cards. |
| Person Portraits | people/ | Transcoded WebP portraits for persons. |
| Error Logs | prks-errors.log | Rotating log for persistent error tracking. |
| Root Marker | prks-root.json | Metadata marker for root identification and generation tracking. |
Sources: README.md:91-102, backend/AGENTS.md:76-80
Persistence Layers
PRKS categorizes stored data into four distinct types for backup and recovery management:
1. Canonical State
This data constitutes the user's research and is essential for backup. It includes the main database (prks_data.db), managed PDFs, and the synchronization ledger. Deletions of canonical records, such as Work entries, must commit the database transaction before performing filesystem cleanup to prevent data loss.
Sources: backend/AGENTS.md:76-80, backend/AGENTS.md:120-128
2. Derived State
Derived components are disposable and rebuildable from canonical state. These include:
- PDF Text Index:
prks_text_index.db(FTS5). - Research Index:
prks_research_index.dbfor note references. - Thumbnails: PDF page images.
Sources: backend/AGENTS.md:82-84, backend/AGENTS.md:103-118
3. Operational State
Operational data manages process coordination and is never included in backups. This includes the root.lock lease file and temporary maintenance markers.
Sources: README.md:126-128, backend/AGENTS.md:66-70
4. Client-Side State
Browser-local storage provides offline capabilities and editor recovery:
- IndexedDB: Used by
offline-store.jsfor a disposable read cache of entities and lists. - Service Worker Cache: Stores the app shell, static assets, and managed PDFs for offline availability.
- Editor Recovery:
prks-editor-recovery-v1IndexedDB for unsaved drafts.
Sources: frontend/sw.js:10-30, frontend/js/offline-runtime.js:12-25, AGENTS.md:493-497
Data Flow and Synchronization
PRKS implements a local-first synchronization protocol that ensures coherence between the server and multiple browser clients.
Backend Deletion and Cleanup Flow
The following diagram illustrates the durable cleanup process for managed PDFs when a Work is deleted:
This flow ensures that if the process crashes after the database commit but before the file unlink, the pending_pdf_cleanup record allows a retry at the next startup.
Sources: backend/AGENTS.md:120-155
Client-Side Coherence Domains
The offline-runtime.js manages coherence domains to invalidate groups of related cached records. A mutation in one entity stales the entire domain to prevent stale data display.
| Domain | Included Entities/Lists |
|---|---|
folders | Folder entities, folders:index |
works-browse | works-browse:index |
people | Person entities, people:index |
concepts | Concept entities, concepts:index |
research-graph-core | Core Research Graph snapshots |
Sources: frontend/js/offline-runtime.js:28-55, frontend/js/offline-runtime.js:906-950
Service Worker Architecture
The service worker (sw.js) provides an app-shell and PDF cache. It uses a staging mechanism to prevent failed installations from corrupting active caches.
This architecture ensures that the PRKS shell only activates offline support when a complete set of essential JS, CSS, and font files is successfully cached.
Sources: frontend/sw.js:26-45, frontend/sw.js:338-360
Summary
The Storage Architecture of PRKS is designed for high reliability and offline resilience. By utilizing strict file locking and a tiered persistence model, the system maintains library integrity across different execution environments. The separation of canonical research data from rebuildable derived indexes allows for efficient backups and recovery while supporting advanced search and visualization features. The progressive transition to a PostgreSQL-capable backend ensures the system's long-term scalability and support for multi-user workflows.
Sources: backend/AGENTS.md:6-15, README.md:143-146