Skip to content

Repository files navigation

Ground

Ground is a private editorial workspace where a Scribble can become a durable Thread. Work and Personal stay separate; time remains quick to record.

Product Shape

  • Desk: one-action thought capture and approximate time logging.
  • Threads: lifecycle, collection, label, and full-text retrieval.
  • Time: an editable 30-day ledger.
  • Review: stale and loose work, recent completions, Personal lenses, and Insights.
  • Thread studio: Tiptap documents with headings, nested lists, checklists, links, formatting, templates, context, autosave, and optimistic version checks.
  • Offline IndexedDB outbox for new Scribbles and time entries. Rich documents remain online-only.

Architecture

Flask serves focused blueprints from ground/ and the locally bundled client. SQLite schema v5 stores threads, documents, collections, labels, time, events, templates, and single-owner passkey credentials. FTS5 provides thread search. Gunicorn runs one worker with four threads because the Railway deployment has one replica and one mounted SQLite volume.

Startup is deliberately volume-aware: bin/start runs the restart-safe migration before Gunicorn. A v3 or v4 journal.json is checksummed and copied to DATA_DIR/backups, migrated into a temporary database, validated with PRAGMA integrity_check and count comparisons, then atomically renamed.

Local Setup

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.lock
npm ci
npm run build
AUTH_MODE=open python app.py

Open http://127.0.0.1:8765. Local data defaults to ./data/ground.sqlite3. To migrate the included sample v4 store in isolation:

DATA_DIR=/tmp/ground-sample DATABASE_PATH=/tmp/ground-sample/ground.sqlite3 \
  AUTH_MODE=open python app.py

Configuration

Variable Default Purpose
APP_ENV development Set to production on Railway.
APP_TIMEZONE Asia/Kolkata Day boundaries and generated timestamps.
DATA_DIR ./data Mounted data and migration backups.
DATABASE_PATH $DATA_DIR/ground.sqlite3 SQLite database.
SECRET_KEY local-only fallback Session and CSRF signing; required in production.
AUTH_MODE open locally, basic in production open, basic, enroll, or passkey.
APP_ORIGIN local URL Exact WebAuthn origin.
WEBAUTHN_RP_ID localhost Stable passkey relying-party domain.
WEBAUTHN_RP_NAME Ground Passkey display name.
SESSION_COOKIE_SECURE false Must be true on Railway.
MAINTENANCE_MODE false Rejects non-auth mutations with stable 503 errors.

APP_USERNAME and APP_PASSWORD protect the enrollment transition only. They must be removed after AUTH_MODE=passkey is verified.

Verification

python -m unittest -v
python -m py_compile app.py ground/*.py
node --check client/app.js
node --check client/offline.js
node --check static/sw.js
git diff --check

Railway

Dockerfile, railway.json, and bin/start define the production build and runtime. The exact maintenance, backup, migration, passkey enrollment, rollback, and post-cutover checks are documented in RAILWAY_ROLLOUT.md. Migration runs inside the application container because Railway pre-deploy containers do not mount persistent volumes.

License

MIT

About

A personal time and intentions tracker built as boutique software.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages