Skip to content

jaimerr/journaling

Repository files navigation

Journal App

A personal journaling application with workspaces and topics, featuring local-first data storage with optional cloud sync.

Architecture

┌─────────────────────────────────────────┐
│   journal.encinas.casa (Netlify)        │
│   Next.js Frontend + API Routes         │
└─────────────────┬───────────────────────┘
                  │
        ┌─────────┴─────────┐
        ▼                   ▼
┌───────────────┐   ┌───────────────┐
│   Supabase    │   │  Mac (Local)  │
│   (Cloud)     │   │               │
│               │   │ • Python API  │
│ • Metadata    │   │ • SQLite DB   │
│ • Sync state  │   │ • Full content│
└───────────────┘   └───────────────┘

Quick Start

  1. Start the application:

    ./start.sh

    This starts both the Python backend (port 8789) and Next.js frontend (port 3009).

  2. Open in browser: http://localhost:3009

Tailscale (remote access to the local API)

start.sh binds Next.js and the Python server to 0.0.0.0 by default so they accept connections from your LAN and from your Tailscale tailnet (the service listens on all interfaces; Tailscale traffic arrives like any other).

  1. On the machine running the journal stack, note its Tailscale IP (e.g. 100.x.y.z).

  2. On the client (laptop, phone browser, or another dev machine), set in .env.local:

    NEXT_PUBLIC_LOCAL_API_URL=http://100.x.y.z:8789

  3. Rebuild or restart Next so the client points at the Mac / Mac Mini hosting SQLite.

The deployed site on Netlify cannot reach 100.x.x.x from the cloud; only browsers on your tailnet can. See Jaime’s hybrid-app notes: use NEXT_PUBLIC_LOCAL_API_URL with the host’s tailnet address when you need the UI to talk to SQLite from another device.

To force localhost-only binding:

NEXTJS_HOST=127.0.0.1 API_BIND_HOST=127.0.0.1 ./start.sh

Agent / OpenClaw API discovery

Full agent runbook (launch, health checks, Tailscale, curls): docs/OPENCLAW.md

Standard JSON envelope and catalog (per family app conventions):

Endpoint Notes
GET http://localhost:3009/api/v1/health Next.js liveness (no auth).
GET http://localhost:3009/api/v1/manifest Full endpoint list (Next + Python).
GET http://localhost:8789/health Python liveness; body uses { success, data, meta }.

Example:

curl -s http://localhost:3009/api/v1/health | jq .
curl -s http://localhost:3009/api/v1/manifest | jq .
curl -s http://localhost:8789/health | jq .

Optional header for future secured routes: X-API-Key (env OPENCLAW_API_KEY). The SQLite Python CRUD routes stay usable from the browser without a key; prefer Tailscale ACLs for exposure control.

Manual Start

If you prefer to start servers separately:

# Terminal 1: Python backend
cd backend
python3 api_server.py

# Terminal 2: Next.js frontend (add -H 0.0.0.0 for Tailscale/LAN, same as start.sh)
npm run dev -- -p 3009 -H 0.0.0.0

Features

  • Workspaces: Organize your journal into different areas (e.g., Professional, Personal, Ideas)
  • Topics: Further categorize entries within each workspace
  • Full-text search: Search across all your entries
  • Markdown support: Write entries in markdown
  • Tags: Add tags to entries for quick filtering
  • Local-first: All content stored locally in SQLite for privacy
  • Cloud sync: Metadata synced to Supabase for backup (optional)

AI Features (requires Claude API key)

  • Workspace Summaries: AI-generated summaries of all notes in a workspace that update incrementally as you add new content
  • AI Writing Companion: Get help while writing - ask for suggestions, explore ideas, or get feedback
  • Related Notes: Find connections between your entries - the AI suggests related notes you can link to

Importing from VooDoo Pad

If you have existing VooDoo Pad (.vpdoc) documents:

# Place .vpdoc files in import_data/ folder
python3 backend/import_voodoopad.py import_data/

Project Structure

journaling/
├── src/                    # Next.js frontend
│   ├── app/               # App router pages
│   ├── components/        # React components
│   │   └── journal/       # Journal-specific components
│   │       ├── ai-companion.tsx     # AI writing assistant
│   │       ├── workspace-summary.tsx # Workspace AI summary
│   │       └── ...
│   └── lib/               # Utilities and API client
├── backend/
│   ├── api_server.py      # Python HTTP server
│   ├── ai_service.py      # Claude AI integration
│   ├── import_voodoopad.py # VooDoo Pad importer
│   ├── venv/              # Python virtual env (for anthropic)
│   └── db/                # SQLite database
├── supabase/
│   └── schema.sql         # Cloud schema
└── start.sh               # Launch script

Environment Variables

See .env.local.example. Create .env.local with at least:

NEXT_PUBLIC_LOCAL_API_URL=http://localhost:8789
NEXT_PUBLIC_SUPABASE_URL=https://absicuhkgkmyjbsswjlr.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_key
NEXT_PUBLIC_APP_NAME=journal

# AI Features (optional - set for AI companion and workspace summaries)
ANTHROPIC_API_KEY=your_anthropic_api_key

# Optional — OpenClaw / agents on new Next.js API routes you protect with validateApiKey
# OPENCLAW_API_KEY=...

To use AI features, you need to:

  1. Get an API key from https://console.anthropic.com/
  2. Add it to your .env.local file
  3. The Python backend will automatically pick it up

Deployment

For production deployment to Netlify:

  1. Push to GitHub
  2. Connect repo to Netlify
  3. Set environment variables
  4. Add custom domain: journal.encinas.casa

Note: The local backend needs to run on your machine for full functionality.

Tech Stack

  • Frontend: Next.js 16, TypeScript, Tailwind CSS, shadcn/ui
  • Local Backend: Python 3, SQLite
  • Cloud: Supabase (PostgreSQL)

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors