- Add weather router with OpenWeatherMap integration and 1-hour cache - Add is_starred column to calendar events with countdown widget - Add weather_city setting with Settings page input - Replace people/locations stats with open todos count + weather card - Add quick-add dropdown (event/todo/reminder) to dashboard header - Make CalendarWidget events single-line thin rows - Add rain warnings to smart briefing when chance > 40% - Invalidate dashboard/upcoming queries on form mutations - Migration 004: is_starred + weather_city columns Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
199 lines
6.7 KiB
Markdown
199 lines
6.7 KiB
Markdown
# UMBRA
|
|
|
|
A self-hosted personal life administration app with a dark-themed UI. Manage your todos, calendar events, projects, reminders, contacts, and locations from a single dashboard.
|
|
|
|
## Features
|
|
|
|
- **Dashboard** - At-a-glance overview with today's events, upcoming todos, active reminders, and project stats
|
|
- **Todos** - Task management with priorities, due dates, and completion tracking
|
|
- **Calendar** - Full interactive calendar (month/week/day views) with drag-and-drop event rescheduling
|
|
- **Projects** - Project boards with nested task lists, status tracking, and progress indicators
|
|
- **Reminders** - Time-based reminders with dismiss functionality
|
|
- **People** - Contact directory with relationship tracking and task assignment
|
|
- **Locations** - Location management with categories
|
|
- **Weather** - Dashboard weather widget with temperature, conditions, and rain warnings
|
|
- **Settings** - Customizable accent color, upcoming days range, weather city, and PIN management
|
|
|
|
## Screenshots
|
|
|
|
*Coming soon*
|
|
|
|
## Tech Stack
|
|
|
|
| Layer | Technology |
|
|
|--------------|------------|
|
|
| Frontend | React 18, TypeScript, Vite, Tailwind CSS |
|
|
| UI Components | Custom shadcn/ui-style components, FullCalendar, Lucide icons |
|
|
| State | TanStack Query v5, React Router v6 |
|
|
| Backend | FastAPI, Python 3.12, Pydantic v2 |
|
|
| Database | PostgreSQL 16, SQLAlchemy 2.0 (async), Alembic |
|
|
| Auth | PIN-based with bcrypt + signed cookies |
|
|
| Deployment | Docker Compose (3 services), Nginx reverse proxy |
|
|
|
|
## Quick Start
|
|
|
|
### Prerequisites
|
|
|
|
- [Docker](https://docs.docker.com/get-docker/) and [Docker Compose](https://docs.docker.com/compose/install/)
|
|
|
|
### Setup
|
|
|
|
1. **Clone the repository**
|
|
```bash
|
|
git clone https://your-gitea-instance/youruser/umbra.git
|
|
cd umbra
|
|
```
|
|
|
|
2. **Configure environment variables**
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
Edit `.env` and set secure values:
|
|
```env
|
|
POSTGRES_USER=umbra
|
|
POSTGRES_PASSWORD=your-secure-password
|
|
POSTGRES_DB=umbra
|
|
DATABASE_URL=postgresql+asyncpg://umbra:your-secure-password@db:5432/umbra
|
|
SECRET_KEY=your-random-secret-key
|
|
OPENWEATHERMAP_API_KEY=your-openweathermap-api-key
|
|
```
|
|
|
|
> **Weather widget**: The dashboard weather widget requires a free [OpenWeatherMap](https://openweathermap.org/api) API key. Set `OPENWEATHERMAP_API_KEY` in `.env`, then configure your city in Settings.
|
|
|
|
3. **Build and run**
|
|
```bash
|
|
docker-compose up --build
|
|
```
|
|
|
|
4. **Open the app**
|
|
|
|
Navigate to `http://localhost` in your browser. On first launch you'll be prompted to create a PIN.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
+-----------+
|
|
| Browser |
|
|
+-----+-----+
|
|
|
|
|
port 80 (HTTP)
|
|
|
|
|
+-------+-------+
|
|
| Nginx |
|
|
| (frontend) |
|
|
+---+-------+---+
|
|
| |
|
|
static | | /api/*
|
|
files | |
|
|
v v
|
|
+---+-------+---+
|
|
| FastAPI |
|
|
| (backend) |
|
|
| port 8000 |
|
|
+-------+-------+
|
|
|
|
|
+-------+-------+
|
|
| PostgreSQL |
|
|
| (db) |
|
|
| port 5432 |
|
|
+---------------+
|
|
```
|
|
|
|
- **Frontend** is built as static files and served by Nginx. Nginx also reverse-proxies API requests to the backend.
|
|
- **Backend** runs Alembic migrations on startup, then serves the FastAPI application.
|
|
- **Database** uses a named Docker volume (`postgres_data`) for persistence.
|
|
|
|
## API Overview
|
|
|
|
All endpoints require authentication (signed session cookie) except auth routes and the health check.
|
|
|
|
| Endpoint | Description |
|
|
|--------------------|-------------|
|
|
| `GET /health` | Health check |
|
|
| `/api/auth/*` | PIN setup, login, logout, status |
|
|
| `/api/todos/*` | Todos CRUD + toggle completion |
|
|
| `/api/events/*` | Calendar events CRUD |
|
|
| `/api/reminders/*` | Reminders CRUD + dismiss |
|
|
| `/api/projects/*` | Projects + nested tasks CRUD |
|
|
| `/api/people/*` | People CRUD |
|
|
| `/api/locations/*` | Locations CRUD |
|
|
| `/api/settings/*` | App settings + PIN change |
|
|
| `/api/dashboard` | Dashboard aggregation |
|
|
| `/api/upcoming` | Unified upcoming items feed |
|
|
|
|
Full API documentation is available at `http://localhost:8000/docs` (Swagger UI) when the backend is running.
|
|
|
|
## Development
|
|
|
|
### Rebuild a single service
|
|
|
|
```bash
|
|
docker-compose up --build backend # Backend only
|
|
docker-compose up --build frontend # Frontend only
|
|
```
|
|
|
|
### View logs
|
|
|
|
```bash
|
|
docker-compose logs -f # All services
|
|
docker-compose logs -f backend # Backend only
|
|
```
|
|
|
|
### Reset database
|
|
|
|
```bash
|
|
docker-compose down -v && docker-compose up --build
|
|
```
|
|
|
|
### Stop all services
|
|
|
|
```bash
|
|
docker-compose down
|
|
```
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
umbra/
|
|
├── docker-compose.yaml
|
|
├── .env / .env.example
|
|
├── backend/
|
|
│ ├── Dockerfile
|
|
│ ├── requirements.txt
|
|
│ ├── start.sh
|
|
│ ├── alembic.ini
|
|
│ ├── alembic/ # Database migrations
|
|
│ └── app/
|
|
│ ├── main.py # FastAPI app entry point
|
|
│ ├── config.py # Environment settings
|
|
│ ├── database.py # Async SQLAlchemy setup
|
|
│ ├── models/ # SQLAlchemy ORM models
|
|
│ ├── schemas/ # Pydantic request/response schemas
|
|
│ └── routers/ # API route handlers
|
|
└── frontend/
|
|
├── Dockerfile
|
|
├── nginx.conf
|
|
├── package.json
|
|
└── src/
|
|
├── App.tsx # Routes and auth guard
|
|
├── lib/api.ts # Axios client
|
|
├── hooks/ # Auth, settings, theme hooks
|
|
├── types/ # TypeScript interfaces
|
|
└── components/
|
|
├── ui/ # Base UI components
|
|
├── layout/ # App shell and sidebar
|
|
├── auth/ # PIN login screen
|
|
├── dashboard/ # Dashboard and widgets
|
|
├── calendar/ # Calendar and event form
|
|
├── todos/ # Todo management
|
|
├── reminders/ # Reminder management
|
|
├── projects/ # Project boards and tasks
|
|
├── people/ # Contact directory
|
|
├── locations/ # Location management
|
|
└── settings/ # App settings
|
|
```
|
|
|
|
## License
|
|
|
|
This project is for personal use. Feel free to fork and adapt for your own needs.
|