feat: v0.1.0 - geolocation capture, calendar, search, Starlight docs site
- Automatic browser geolocation capture on event creation - Reverse geocoding via Nominatim API for place names - Full-text search with SQLite FTS5 - Calendar view for browsing past entries - DateNavigator component for day navigation - SearchModal with Ctrl+K shortcut - QuickAddWidget with Ctrl+J shortcut - Starlight documentation site with GitHub Pages deployment - Multiple AI provider support (Groq, OpenAI, Anthropic, Ollama, LM Studio) - Multi-user registration support BREAKING: Events now include latitude/longitude/placeName fields
This commit is contained in:
15
docs/src/assets/logo-dark.svg
Normal file
15
docs/src/assets/logo-dark.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<defs>
|
||||
<linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#a78bfa;stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:#818cf8;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="100" height="100" rx="20" fill="url(#grad)"/>
|
||||
<path d="M25 25 L75 25 L75 80 L25 80 Z" fill="none" stroke="white" stroke-width="3" stroke-linecap="round"/>
|
||||
<path d="M35 40 L65 40" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M35 50 L65 50" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M35 60 L55 60" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
<circle cx="70" cy="60" r="8" fill="white" opacity="0.3"/>
|
||||
<path d="M70 55 L70 65 M65 60 L75 60" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 897 B |
15
docs/src/assets/logo-light.svg
Normal file
15
docs/src/assets/logo-light.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<defs>
|
||||
<linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#8b5cf6;stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:#6366f1;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="100" height="100" rx="20" fill="url(#grad)"/>
|
||||
<path d="M25 25 L75 25 L75 80 L25 80 Z" fill="none" stroke="white" stroke-width="3" stroke-linecap="round"/>
|
||||
<path d="M35 40 L65 40" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M35 50 L65 50" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M35 60 L55 60" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
<circle cx="70" cy="60" r="8" fill="white" opacity="0.3"/>
|
||||
<path d="M70 55 L70 65 M65 60 L75 60" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 897 B |
47
docs/src/content/docs/api/authentication.mdx
Normal file
47
docs/src/content/docs/api/authentication.mdx
Normal file
@@ -0,0 +1,47 @@
|
||||
---
|
||||
title: Authentication
|
||||
description: API authentication methods
|
||||
sidebar:
|
||||
order: 1
|
||||
---
|
||||
|
||||
## API Key Authentication
|
||||
|
||||
All API requests require authentication using a Bearer token:
|
||||
|
||||
```http
|
||||
Authorization: Bearer your-api-key-here
|
||||
```
|
||||
|
||||
## Getting an API Key
|
||||
|
||||
### Via Login
|
||||
|
||||
1. POST to `/api/v1/auth/login` with email/password
|
||||
2. Receive JWT token
|
||||
3. Create API key via POST to `/api/v1/auth/api-key`
|
||||
|
||||
### Via Registration
|
||||
|
||||
1. POST to `/api/v1/auth/register` with email/password
|
||||
2. Receive API key directly
|
||||
|
||||
## Response Format
|
||||
|
||||
All endpoints return:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": { ... } | null,
|
||||
"error": { "code": "ERROR_CODE", "message": "Error description" } | null
|
||||
}
|
||||
```
|
||||
|
||||
## Error Codes
|
||||
|
||||
| Code | HTTP Status | Description |
|
||||
|------|-------------|-------------|
|
||||
| `UNAUTHORIZED` | 401 | Invalid or missing API key |
|
||||
| `NOT_FOUND` | 404 | Resource not found |
|
||||
| `VALIDATION_ERROR` | 400 | Invalid request data |
|
||||
| `EVENT_IMMUTABLE` | 400 | Cannot modify locked events |
|
||||
70
docs/src/content/docs/api/events.mdx
Normal file
70
docs/src/content/docs/api/events.mdx
Normal file
@@ -0,0 +1,70 @@
|
||||
---
|
||||
title: Events API
|
||||
description: Events endpoints reference
|
||||
sidebar:
|
||||
order: 2
|
||||
---
|
||||
|
||||
## Create Event
|
||||
|
||||
```http
|
||||
POST /api/v1/events
|
||||
```
|
||||
|
||||
### Request Body
|
||||
|
||||
```json
|
||||
{
|
||||
"date": "2024-01-15",
|
||||
"type": "text",
|
||||
"content": "Had coffee with Sarah",
|
||||
"latitude": 40.7128,
|
||||
"longitude": -74.0060,
|
||||
"placeName": "New York, NY"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `date` | string | Yes | Date in YYYY-MM-DD format |
|
||||
| `type` | string | Yes | One of: event, text, photo, voice, health |
|
||||
| `content` | string | Yes | Event content |
|
||||
| `latitude` | number | No | GPS latitude |
|
||||
| `longitude` | number | No | GPS longitude |
|
||||
| `placeName` | string | No | Reverse-geocoded place name |
|
||||
| `metadata` | object | No | Additional metadata |
|
||||
|
||||
### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"id": "uuid",
|
||||
"date": "2024-01-15",
|
||||
"type": "text",
|
||||
"content": "Had coffee with Sarah",
|
||||
"latitude": 40.7128,
|
||||
"longitude": -74.0060,
|
||||
"placeName": "New York, NY",
|
||||
"createdAt": "2024-01-15T10:30:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Get Day
|
||||
|
||||
```http
|
||||
GET /api/v1/days/:date
|
||||
```
|
||||
|
||||
Returns all events and journal for a specific date.
|
||||
|
||||
## Delete Event
|
||||
|
||||
```http
|
||||
DELETE /api/v1/events/:id
|
||||
```
|
||||
|
||||
:::caution
|
||||
Cannot delete events from days with generated journals.
|
||||
:::
|
||||
80
docs/src/content/docs/api/journals.mdx
Normal file
80
docs/src/content/docs/api/journals.mdx
Normal file
@@ -0,0 +1,80 @@
|
||||
---
|
||||
title: Journals API
|
||||
description: Journals endpoints reference
|
||||
sidebar:
|
||||
order: 3
|
||||
---
|
||||
|
||||
## Generate Diary
|
||||
|
||||
```http
|
||||
POST /api/v1/journal/generate/:date
|
||||
```
|
||||
|
||||
### Request Body
|
||||
|
||||
```json
|
||||
{
|
||||
"instructions": "Make it more detailed and poetic"
|
||||
}
|
||||
```
|
||||
|
||||
### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"journal": {
|
||||
"id": "uuid",
|
||||
"date": "2024-01-15",
|
||||
"title": "A Productive Tuesday",
|
||||
"content": "Full diary content...",
|
||||
"eventCount": 8,
|
||||
"generatedAt": "2024-01-15T22:00:00Z"
|
||||
},
|
||||
"task": {
|
||||
"id": "uuid",
|
||||
"status": "completed",
|
||||
"provider": "groq",
|
||||
"model": "llama-3.3-70b-versatile"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Get Journal
|
||||
|
||||
```http
|
||||
GET /api/v1/journal/:date
|
||||
```
|
||||
|
||||
Returns the diary page for a specific date.
|
||||
|
||||
## List Journals
|
||||
|
||||
```http
|
||||
GET /api/v1/journals?page=1&limit=10
|
||||
```
|
||||
|
||||
### Query Parameters
|
||||
|
||||
| Parameter | Default | Description |
|
||||
|-----------|---------|-------------|
|
||||
| `page` | 1 | Page number |
|
||||
| `limit` | 10 | Items per page (10, 50, or 100) |
|
||||
|
||||
## Get Generation Tasks
|
||||
|
||||
```http
|
||||
GET /api/v1/journal/:date/tasks
|
||||
```
|
||||
|
||||
Returns all generation attempts for a journal with request/response JSON.
|
||||
|
||||
## Delete Journal
|
||||
|
||||
```http
|
||||
DELETE /api/v1/journal/:date
|
||||
```
|
||||
|
||||
Deleting a journal **unlocks** all events for that day, allowing edits and new entries.
|
||||
80
docs/src/content/docs/api/settings.mdx
Normal file
80
docs/src/content/docs/api/settings.mdx
Normal file
@@ -0,0 +1,80 @@
|
||||
---
|
||||
title: Settings API
|
||||
description: Settings endpoints reference
|
||||
sidebar:
|
||||
order: 4
|
||||
---
|
||||
|
||||
## Get Settings
|
||||
|
||||
```http
|
||||
GET /api/v1/settings
|
||||
```
|
||||
|
||||
### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"aiProvider": "groq",
|
||||
"aiApiKey": null,
|
||||
"aiModel": "llama-3.3-70b-versatile",
|
||||
"journalPrompt": "Custom instructions...",
|
||||
"language": "en",
|
||||
"timezone": "UTC",
|
||||
"journalContextDays": 10,
|
||||
"providerSettings": {
|
||||
"groq": { "apiKey": "...", "model": "..." }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Update Settings
|
||||
|
||||
```http
|
||||
PUT /api/v1/settings
|
||||
```
|
||||
|
||||
### Request Body
|
||||
|
||||
```json
|
||||
{
|
||||
"aiProvider": "openai",
|
||||
"aiApiKey": "sk-...",
|
||||
"journalPrompt": "Write in a reflective tone"
|
||||
}
|
||||
```
|
||||
|
||||
### Fields
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `aiProvider` | string | groq, openai, anthropic, ollama, lmstudio |
|
||||
| `aiApiKey` | string | API key for selected provider |
|
||||
| `aiModel` | string | Model identifier |
|
||||
| `journalPrompt` | string | Custom instructions (null to clear) |
|
||||
| `journalContextDays` | number | Days of previous journals to include (0-30) |
|
||||
|
||||
## Change Password
|
||||
|
||||
```http
|
||||
POST /api/v1/account/password
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"currentPassword": "old-password",
|
||||
"newPassword": "new-secure-password"
|
||||
}
|
||||
```
|
||||
|
||||
## Delete Account
|
||||
|
||||
```http
|
||||
DELETE /api/v1/account
|
||||
```
|
||||
|
||||
:::danger
|
||||
This permanently deletes your account and all data. This cannot be undone.
|
||||
:::
|
||||
93
docs/src/content/docs/deployment/docker.mdx
Normal file
93
docs/src/content/docs/deployment/docker.mdx
Normal file
@@ -0,0 +1,93 @@
|
||||
---
|
||||
title: Docker Deployment
|
||||
description: Deploy DearDiary with Docker
|
||||
sidebar:
|
||||
order: 1
|
||||
---
|
||||
|
||||
## Docker Compose
|
||||
|
||||
The recommended way to run DearDiary:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- ./data:/data
|
||||
env_file:
|
||||
- backend/.env
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
## Running
|
||||
|
||||
### Start
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### Stop
|
||||
|
||||
```bash
|
||||
docker compose down
|
||||
```
|
||||
|
||||
### Rebuild
|
||||
|
||||
```bash
|
||||
docker compose build && docker compose up -d
|
||||
```
|
||||
|
||||
## Volumes
|
||||
|
||||
Data persists in `./data/`:
|
||||
|
||||
| Directory | Contents |
|
||||
|-----------|----------|
|
||||
| `data/db/` | SQLite database |
|
||||
| `data/media/` | Uploaded files |
|
||||
|
||||
## Health Check
|
||||
|
||||
The app exposes a health endpoint:
|
||||
|
||||
```http
|
||||
GET http://localhost:8080/health
|
||||
```
|
||||
|
||||
Returns:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"timestamp": "2024-01-15T10:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
## Production Considerations
|
||||
|
||||
### Reverse Proxy
|
||||
|
||||
For production, use a reverse proxy (nginx, Caddy, Traefik) with:
|
||||
|
||||
- HTTPS/TLS termination
|
||||
- Security headers
|
||||
- Rate limiting
|
||||
|
||||
### Database
|
||||
|
||||
Default SQLite is fine for single-user or small deployments.
|
||||
|
||||
For multi-user or high traffic, consider PostgreSQL:
|
||||
|
||||
```env
|
||||
DATABASE_URL="postgresql://user:pass@host:5432/deardiary"
|
||||
```
|
||||
|
||||
### Backup
|
||||
|
||||
Regularly backup `./data/` directory.
|
||||
66
docs/src/content/docs/deployment/environment.mdx
Normal file
66
docs/src/content/docs/deployment/environment.mdx
Normal file
@@ -0,0 +1,66 @@
|
||||
---
|
||||
title: Environment Variables
|
||||
description: Complete environment variable reference
|
||||
sidebar:
|
||||
order: 2
|
||||
---
|
||||
|
||||
## Configuration File
|
||||
|
||||
Copy `.env.example` to `.env`:
|
||||
|
||||
```bash
|
||||
cp backend/.env.example backend/.env
|
||||
```
|
||||
|
||||
## Variables
|
||||
|
||||
### Application
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `APP_NAME` | DearDiary | App name displayed in UI |
|
||||
| `VERSION` | 0.1.0 | App version |
|
||||
| `PORT` | 3000 | Internal API port |
|
||||
|
||||
### Database
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `DATABASE_URL` | file:./data/deardiary.db | SQLite by default |
|
||||
| `DATABASE_URL` | postgresql://... | PostgreSQL connection |
|
||||
| `DATABASE_URL` | mysql://... | MySQL connection |
|
||||
|
||||
### Security
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `JWT_SECRET` | development-secret... | **Required in production!** |
|
||||
| `CORS_ORIGIN` | * | CORS allowed origins |
|
||||
|
||||
### User Management
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `REGISTRATION_ENABLED` | false | Enable/disable registration |
|
||||
| `DEFAULT_USER_EMAIL` | admin@localhost | Default admin email |
|
||||
| `DEFAULT_USER_PASSWORD` | changeme123 | Default admin password |
|
||||
|
||||
### Storage
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `MEDIA_DIR` | ./data/media | Media files directory |
|
||||
|
||||
## Production Checklist
|
||||
|
||||
:::caution
|
||||
Before going to production:
|
||||
|
||||
1. Set a strong `JWT_SECRET`
|
||||
2. Set `CORS_ORIGIN` to your domain
|
||||
3. Change default admin credentials
|
||||
4. Set `REGISTRATION_ENABLED=false` if not needed
|
||||
5. Use HTTPS/TLS
|
||||
6. Set up regular backups
|
||||
:::
|
||||
62
docs/src/content/docs/features/ai-providers.mdx
Normal file
62
docs/src/content/docs/features/ai-providers.mdx
Normal file
@@ -0,0 +1,62 @@
|
||||
---
|
||||
title: AI Providers
|
||||
description: Configure AI providers for diary generation
|
||||
sidebar:
|
||||
order: 3
|
||||
---
|
||||
|
||||
## Supported Providers
|
||||
|
||||
DearDiary supports multiple AI providers:
|
||||
|
||||
| Provider | Default Model | Type |
|
||||
|----------|---------------|------|
|
||||
| **Groq** | llama-3.3-70b-versatile | Cloud |
|
||||
| OpenAI | gpt-4o | Cloud |
|
||||
| Anthropic | claude-3.5-sonnet | Cloud |
|
||||
| Ollama | varies | Local |
|
||||
| LM Studio | varies | Local |
|
||||
|
||||
## Groq (Recommended)
|
||||
|
||||
Free tier available. Fast inference.
|
||||
|
||||
1. Get an API key from [console.groq.com](https://console.groq.com)
|
||||
2. Enter the API key in Settings
|
||||
3. Select Groq as your provider
|
||||
|
||||
## OpenAI
|
||||
|
||||
1. Get an API key from [platform.openai.com](https://platform.openai.com)
|
||||
2. Optionally select a specific model:
|
||||
- `gpt-4o` - Most capable
|
||||
- `gpt-4o-mini` - Faster, cheaper
|
||||
|
||||
## Anthropic
|
||||
|
||||
1. Get an API key from [console.anthropic.com](https://console.anthropic.com)
|
||||
2. Select Claude model:
|
||||
- `claude-3-5-sonnet-latest` - Recommended
|
||||
- `claude-3-opus-latest` - Most capable
|
||||
|
||||
## Ollama (Local)
|
||||
|
||||
Run models locally on your machine.
|
||||
|
||||
1. Install [Ollama](https://ollama.ai)
|
||||
2. Pull a model: `ollama pull llama3.2`
|
||||
3. Set base URL: `http://localhost:11434/v1`
|
||||
4. Select model name
|
||||
|
||||
## LM Studio (Local)
|
||||
|
||||
Alternative local option with GUI.
|
||||
|
||||
1. Download [LM Studio](https://lmstudio.ai)
|
||||
2. Download a model
|
||||
3. Start local server (click "Start Server")
|
||||
4. Set base URL: `http://localhost:1234/v1`
|
||||
|
||||
## Testing Connection
|
||||
|
||||
Use the **Test Connection** button in Settings to verify your AI provider is working before generating diaries.
|
||||
44
docs/src/content/docs/features/calendar.mdx
Normal file
44
docs/src/content/docs/features/calendar.mdx
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
title: Calendar
|
||||
description: Visual calendar view of your journals
|
||||
sidebar:
|
||||
order: 5
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
The Calendar view provides a monthly overview of your journal activity.
|
||||
|
||||
Access it via the navigation menu: **Calendar**
|
||||
|
||||
## Calendar Indicators
|
||||
|
||||
Each day shows:
|
||||
|
||||
| Indicator | Meaning |
|
||||
|-----------|---------|
|
||||
| **Number** | Day of month |
|
||||
| **Filled circle** | Has events |
|
||||
| **Purple border** | Has generated diary page |
|
||||
| **Today** | Highlighted border |
|
||||
|
||||
## Navigation
|
||||
|
||||
- **Previous/Next Month** - Arrow buttons
|
||||
- **Month/Year Picker** - Click month name
|
||||
- **Today Button** - Jump to current date
|
||||
|
||||
## Clicking a Day
|
||||
|
||||
Click any day to view:
|
||||
|
||||
- All events for that day
|
||||
- Diary page if generated
|
||||
- Option to add new events (if unlocked)
|
||||
|
||||
## Use Cases
|
||||
|
||||
- Quickly see activity patterns
|
||||
- Identify gaps in journaling
|
||||
- Navigate to specific past dates
|
||||
- Plan when to catch up on entries
|
||||
60
docs/src/content/docs/features/diary-pages.mdx
Normal file
60
docs/src/content/docs/features/diary-pages.mdx
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
title: Diary Pages
|
||||
description: AI-generated diary entries
|
||||
sidebar:
|
||||
order: 2
|
||||
---
|
||||
|
||||
## What is a Diary Page?
|
||||
|
||||
A **Diary Page** is an AI-generated narrative summary of your day's events. Unlike events, diary pages:
|
||||
|
||||
- Can be regenerated (rewritten)
|
||||
- Include a generated title
|
||||
- Are narrative, not just data points
|
||||
|
||||
## Generating a Diary
|
||||
|
||||
1. Navigate to **Today** (`/today`)
|
||||
2. Ensure you have at least one event
|
||||
3. Click **Generate Diary Page**
|
||||
4. Wait for AI processing
|
||||
|
||||
## Viewing Diary Pages
|
||||
|
||||
Access diary pages via:
|
||||
|
||||
- **Dashboard** - Recent diary excerpts
|
||||
- **Diary** - Paginated list of all diaries
|
||||
- **Calendar** - Visual overview with indicators
|
||||
- **Day View** - Click any date to see its diary
|
||||
|
||||
## Rewriting
|
||||
|
||||
Click **Rewrite** to regenerate with additional instructions:
|
||||
|
||||
### Default Rewrite
|
||||
|
||||
Regenerates with the same events and default prompt.
|
||||
|
||||
### Custom Instructions
|
||||
|
||||
Add specific guidance:
|
||||
|
||||
```
|
||||
Make it more poetic and reflective.
|
||||
Focus on the conversations I had.
|
||||
```
|
||||
|
||||
## Title Generation
|
||||
|
||||
Each diary page includes an AI-generated title (max 50 characters) that summarizes the day.
|
||||
|
||||
## Task History
|
||||
|
||||
Every generation attempt is logged as a **Task**, including:
|
||||
|
||||
- Request/response JSON for debugging
|
||||
- Provider and model used
|
||||
- Success/failure status
|
||||
- Processing time
|
||||
60
docs/src/content/docs/features/events.mdx
Normal file
60
docs/src/content/docs/features/events.mdx
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
title: Events
|
||||
description: Capturing and managing events
|
||||
sidebar:
|
||||
order: 1
|
||||
---
|
||||
|
||||
## What is an Event?
|
||||
|
||||
An **Event** is a single log entry in your journal. Events can be:
|
||||
|
||||
- **Text** - Simple text notes
|
||||
- **Photo** - Captured moments with images
|
||||
- **Voice** - Voice memos
|
||||
- **Health** - Health-related observations
|
||||
- **Event** - General activity logs
|
||||
|
||||
## Creating Events
|
||||
|
||||
### Via Today Page
|
||||
|
||||
1. Navigate to **Today** (`/today`)
|
||||
2. Type your event in the input field
|
||||
3. Select the event type
|
||||
4. Press Enter or click Add
|
||||
|
||||
### Via Quick Add
|
||||
|
||||
Press `Ctrl + J` from anywhere to open the quick add widget.
|
||||
|
||||
## Location
|
||||
|
||||
Events automatically capture:
|
||||
|
||||
- GPS coordinates (if browser permits)
|
||||
- Reverse-geocoded place names
|
||||
|
||||
This helps you remember where things happened.
|
||||
|
||||
## Immutability
|
||||
|
||||
Once a **Diary Page** is generated for a day, all events for that day become **locked**:
|
||||
|
||||
- Cannot be deleted
|
||||
- Cannot be edited
|
||||
- Cannot have new events added
|
||||
|
||||
To unlock, you must delete the diary page.
|
||||
|
||||
## Media
|
||||
|
||||
### Photos
|
||||
|
||||
Upload photos directly or attach them to existing events.
|
||||
|
||||
### Voice Memos
|
||||
|
||||
Record voice memos using your browser's microphone.
|
||||
|
||||
Media files are stored in `./data/media/{userId}/{date}/`
|
||||
72
docs/src/content/docs/features/export-import.mdx
Normal file
72
docs/src/content/docs/features/export-import.mdx
Normal file
@@ -0,0 +1,72 @@
|
||||
---
|
||||
title: Export & Import
|
||||
description: Backup and restore your data
|
||||
sidebar:
|
||||
order: 6
|
||||
---
|
||||
|
||||
## Why Export?
|
||||
|
||||
Regular exports ensure you never lose your data:
|
||||
|
||||
- Backup to external storage
|
||||
- Migrate to new server
|
||||
- Keep offline archive
|
||||
|
||||
## Export Format
|
||||
|
||||
Exports are JSON files containing:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "0.0.6",
|
||||
"exportedAt": "2024-01-15T10:30:00Z",
|
||||
"settings": { ... },
|
||||
"events": [ ... ],
|
||||
"journals": [ ... ],
|
||||
"tasks": [ ... ]
|
||||
}
|
||||
```
|
||||
|
||||
### Included Data
|
||||
|
||||
- **Settings** - AI provider, model, custom prompts
|
||||
- **Events** - All event data including location
|
||||
- **Journals** - All generated diary pages
|
||||
- **Tasks** - Generation history for debugging
|
||||
|
||||
## How to Export
|
||||
|
||||
1. Go to **Settings**
|
||||
2. Scroll to **Data Management**
|
||||
3. Click **Export Data**
|
||||
4. Save the JSON file
|
||||
|
||||
## Import
|
||||
|
||||
### Version Compatibility
|
||||
|
||||
- Minimum supported: 0.0.3
|
||||
- Current version: 0.0.6
|
||||
|
||||
Older exports may lose some data or fail to import.
|
||||
|
||||
### Import Steps
|
||||
|
||||
1. Go to **Settings** → **Data Management**
|
||||
2. Click **Import Data**
|
||||
3. Select your JSON export file
|
||||
4. Review the preview (imported/skipped counts)
|
||||
5. Click **Confirm Import**
|
||||
|
||||
### Duplicate Handling
|
||||
|
||||
- **Events**: Skipped if identical (date + content + timestamp)
|
||||
- **Journals**: Skipped by date
|
||||
- **Tasks**: Linked to existing journals
|
||||
|
||||
## Danger Zone
|
||||
|
||||
:::caution
|
||||
The **Reset Account** option in Danger Zone deletes ALL your data except settings. Use with extreme caution!
|
||||
:::
|
||||
66
docs/src/content/docs/features/media.mdx
Normal file
66
docs/src/content/docs/features/media.mdx
Normal file
@@ -0,0 +1,66 @@
|
||||
---
|
||||
title: Media Uploads
|
||||
description: Photos and voice memos
|
||||
sidebar:
|
||||
order: 7
|
||||
---
|
||||
|
||||
## Supported Media Types
|
||||
|
||||
### Photos
|
||||
|
||||
- Upload photos to accompany events
|
||||
- JPEG, PNG, GIF, WebP supported
|
||||
- Displayed inline in event list
|
||||
|
||||
### Voice Memos
|
||||
|
||||
- Record voice notes
|
||||
- WebM audio format
|
||||
- Playback controls in event list
|
||||
|
||||
## How to Add Media
|
||||
|
||||
### Photo Type Events
|
||||
|
||||
1. Select **Photo** type when creating event
|
||||
2. Add description in text field
|
||||
3. Upload photo
|
||||
|
||||
### Voice Type Events
|
||||
|
||||
1. Select **Voice** type
|
||||
2. Click microphone button
|
||||
3. Start recording
|
||||
4. Stop when finished
|
||||
5. Add optional text note
|
||||
|
||||
## Storage
|
||||
|
||||
Media files are stored at:
|
||||
|
||||
```
|
||||
./data/media/{userId}/{date}/
|
||||
```
|
||||
|
||||
For example:
|
||||
```
|
||||
./data/media/user123abc/2024-01-15/photo.jpg
|
||||
./data/media/user123abc/2024-01-15/voice.webm
|
||||
```
|
||||
|
||||
## Serving
|
||||
|
||||
Media is served via nginx at `/media/` route:
|
||||
|
||||
```
|
||||
/media/{userId}/{date}/{filename}
|
||||
```
|
||||
|
||||
## Privacy
|
||||
|
||||
Media files are:
|
||||
- Stored locally only
|
||||
- Associated with your user account
|
||||
- Not shared between users
|
||||
- Deleted when you delete events
|
||||
43
docs/src/content/docs/features/search.mdx
Normal file
43
docs/src/content/docs/features/search.mdx
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
title: Search
|
||||
description: Finding events and diary pages
|
||||
sidebar:
|
||||
order: 4
|
||||
---
|
||||
|
||||
## Using Search
|
||||
|
||||
Press `Ctrl + K` from anywhere to open the search modal.
|
||||
|
||||
## What You Can Search
|
||||
|
||||
### Diary Pages
|
||||
|
||||
Search across all generated diary pages:
|
||||
|
||||
- Titles
|
||||
- Full content
|
||||
- Dates
|
||||
|
||||
### Events
|
||||
|
||||
Search across all events:
|
||||
|
||||
- Event content
|
||||
- Event type
|
||||
- Date
|
||||
|
||||
## How It Works
|
||||
|
||||
DearDiary uses **SQLite FTS5** (Full-Text Search) for fast, indexed searching:
|
||||
|
||||
1. Automatic indexing on content creation
|
||||
2. Porter stemming for better matches
|
||||
3. Fallback to LIKE queries if FTS fails
|
||||
|
||||
## Tips
|
||||
|
||||
- Use specific keywords for better results
|
||||
- Search works across all dates
|
||||
- Results are grouped by type (diaries vs events)
|
||||
- Click any result to navigate directly to that item
|
||||
54
docs/src/content/docs/getting-started/configuration.mdx
Normal file
54
docs/src/content/docs/getting-started/configuration.mdx
Normal file
@@ -0,0 +1,54 @@
|
||||
---
|
||||
title: Configuration
|
||||
description: Configure DearDiary for your needs
|
||||
sidebar:
|
||||
order: 3
|
||||
---
|
||||
|
||||
## Settings Page
|
||||
|
||||
Access settings via the navigation menu. Settings are organized into sections:
|
||||
|
||||
### AI Provider
|
||||
|
||||
Choose your AI provider for diary generation:
|
||||
|
||||
| Provider | Model | Notes |
|
||||
|----------|-------|-------|
|
||||
| **Groq** (default) | llama-3.3-70b-versatile | Fast, free tier available |
|
||||
| OpenAI | gpt-4o, gpt-4o-mini | Requires API key |
|
||||
| Anthropic | claude-3.5-sonnet | Requires API key |
|
||||
| Ollama | Various | Local models |
|
||||
| LM Studio | Various | Local models |
|
||||
|
||||
### Custom Instructions
|
||||
|
||||
Add custom instructions that are prepended to the default AI prompt:
|
||||
|
||||
```
|
||||
Write in a poetic style.
|
||||
Focus on health and wellness aspects.
|
||||
```
|
||||
|
||||
### Journal Context
|
||||
|
||||
Set how many previous days of diaries the AI considers when generating new entries (0-30 days).
|
||||
|
||||
## Environment Variables
|
||||
|
||||
See [Environment Variables](/deployment/environment) for server-side configuration.
|
||||
|
||||
## Multi-User Setup
|
||||
|
||||
Enable user registration:
|
||||
|
||||
```env
|
||||
REGISTRATION_ENABLED=true
|
||||
```
|
||||
|
||||
Or create a default admin user:
|
||||
|
||||
```env
|
||||
DEFAULT_USER_EMAIL=admin@example.com
|
||||
DEFAULT_USER_PASSWORD=your-secure-password
|
||||
```
|
||||
56
docs/src/content/docs/getting-started/installation.mdx
Normal file
56
docs/src/content/docs/getting-started/installation.mdx
Normal file
@@ -0,0 +1,56 @@
|
||||
---
|
||||
title: Installation
|
||||
description: How to install and set up DearDiary
|
||||
sidebar:
|
||||
order: 1
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [Docker](https://docs.docker.com/get-docker/) and Docker Compose
|
||||
- Git
|
||||
|
||||
## Quick Install
|
||||
|
||||
1. Clone the repository:
|
||||
```bash
|
||||
git clone https://github.com/anomalyco/totalrecall.git
|
||||
cd totalrecall
|
||||
```
|
||||
|
||||
2. Copy the environment file:
|
||||
```bash
|
||||
cp backend/.env.example backend/.env
|
||||
```
|
||||
|
||||
3. Start with Docker:
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
4. Access the app at `http://localhost:8080`
|
||||
|
||||
## Default Credentials
|
||||
|
||||
On first start, a default user is created if configured:
|
||||
|
||||
- **Email**: `admin@localhost` (configurable via `DEFAULT_USER_EMAIL`)
|
||||
- **Password**: `changeme123` (configurable via `DEFAULT_USER_PASSWORD`)
|
||||
|
||||
:::tip
|
||||
Change these credentials immediately after first login!
|
||||
:::
|
||||
|
||||
## Ports
|
||||
|
||||
| Service | Port | Description |
|
||||
|---------|------|-------------|
|
||||
| App | 8080 | Main application (nginx) |
|
||||
| API | 3000 | Backend API (internal) |
|
||||
|
||||
## Data Storage
|
||||
|
||||
All data is stored in Docker volumes:
|
||||
|
||||
- `./data/db/` - SQLite database
|
||||
- `./data/media/` - Uploaded photos and voice memos
|
||||
58
docs/src/content/docs/getting-started/quick-start.mdx
Normal file
58
docs/src/content/docs/getting-started/quick-start.mdx
Normal file
@@ -0,0 +1,58 @@
|
||||
---
|
||||
title: Quick Start
|
||||
description: Get started with DearDiary in 5 minutes
|
||||
sidebar:
|
||||
order: 2
|
||||
---
|
||||
|
||||
## First Steps
|
||||
|
||||
### 1. Log an Event
|
||||
|
||||
Navigate to **Today** and start logging events:
|
||||
|
||||
- Type your event and press Enter
|
||||
- Use the type buttons to change event category (Event, Health, Photo, Voice)
|
||||
- Events are timestamped automatically
|
||||
|
||||
### 2. Add Your Location
|
||||
|
||||
When you log an event, DearDiary automatically captures:
|
||||
|
||||
- **Latitude/Longitude** from your browser
|
||||
- **Place Name** via reverse geocoding (OpenStreetMap)
|
||||
|
||||
:::note
|
||||
Location access requires browser permission. Grant it when prompted for automatic geolocation.
|
||||
:::
|
||||
|
||||
### 3. Generate Your Diary
|
||||
|
||||
When you're ready to lock in your day:
|
||||
|
||||
1. Click **Generate Diary Page**
|
||||
2. AI analyzes all your events
|
||||
3. Creates a narrative diary entry with title
|
||||
|
||||
Once generated, events become **locked** (immutable).
|
||||
|
||||
### 4. Rewrite if Needed
|
||||
|
||||
Click **Rewrite** to regenerate with additional instructions:
|
||||
|
||||
- Add context like "Make it more detailed"
|
||||
- Include specific topics to emphasize
|
||||
- Adjust the tone or style
|
||||
|
||||
## Keyboard Shortcuts
|
||||
|
||||
| Shortcut | Action |
|
||||
|----------|--------|
|
||||
| `Ctrl + J` | Quick add event |
|
||||
| `Ctrl + K` | Search |
|
||||
|
||||
## Tips
|
||||
|
||||
- Log events throughout the day for richer diaries
|
||||
- Use the calendar view to browse past days
|
||||
- Export your data regularly for backup
|
||||
34
docs/src/content/docs/index.mdx
Normal file
34
docs/src/content/docs/index.mdx
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
title: DearDiary
|
||||
description: AI-Powered Daily Journal
|
||||
template: splash
|
||||
hero:
|
||||
title: DearDiary
|
||||
tagline: Your AI-powered daily journal. Capture events throughout the day and let AI transform them into beautiful diary pages.
|
||||
image:
|
||||
file: ../../assets/logo-light.svg
|
||||
actions:
|
||||
- theme: brand
|
||||
text: Get Started
|
||||
link: /getting-started/installation/
|
||||
- theme: alt
|
||||
text: View on GitHub
|
||||
link: https://github.com/anomalyco/totalrecall
|
||||
---
|
||||
|
||||
import { Card, CardGrid } from '@astrojs/starlight/components';
|
||||
|
||||
<CardGrid stagger>
|
||||
<Card title="Capture Events">
|
||||
Log events throughout your day - text, photos, voice memos, and health data.
|
||||
</Card>
|
||||
<Card title="AI-Generated Diary">
|
||||
Let AI transform your events into beautiful, narrative diary pages.
|
||||
</Card>
|
||||
<Card title="Privacy First">
|
||||
Self-hosted. Your data stays on your server.
|
||||
</Card>
|
||||
<Card title="Geolocation">
|
||||
Events are automatically tagged with your location.
|
||||
</Card>
|
||||
</CardGrid>
|
||||
21
docs/src/styles/custom.css
Normal file
21
docs/src/styles/custom.css
Normal file
@@ -0,0 +1,21 @@
|
||||
/* Custom DearDiary styling */
|
||||
:root[data-theme='light'] {
|
||||
--sl-color-accent-low: #e9e3ff;
|
||||
--sl-color-accent: #7c3aed;
|
||||
--sl-color-accent-high: #4c1d95;
|
||||
--sl-color-white: #1e1b4b;
|
||||
--sl-color-gray-1: #3730a3;
|
||||
--sl-color-gray-2: #4338ca;
|
||||
--sl-color-gray-3: #4f46e5;
|
||||
--sl-color-gray-4: #6366f1;
|
||||
--sl-color-gray-5: #818cf8;
|
||||
--sl-color-gray-6: #a5b4fc;
|
||||
--sl-color-gray-7: #c7d2fe;
|
||||
--sl-color-black: #e0e7ff;
|
||||
}
|
||||
|
||||
:root[data-theme='dark'] {
|
||||
--sl-color-accent-low: #4c1d95;
|
||||
--sl-color-accent: #a78bfa;
|
||||
--sl-color-accent-high: #c4b5fd;
|
||||
}
|
||||
Reference in New Issue
Block a user