Organize/README.md

187 lines
8.2 KiB
Markdown

# Organize
A self-hosted, installable PWA for staying organized: an extended to-do
list and notes organizer laid out as a Kanban-style board.
- **Categories** are the board's lanes (e.g. "To Do", "In Progress", "Done").
- **Groups** are the cards within a lane — each has a color, a markdown
notes panel, and a to-do list, and can be dragged between lanes.
- **To-Dos** live inside a Group, with an optional details field.
Accounts are required (there's no anonymous/local-only mode — the board
needs a database to persist to), and the first account ever created on a
given instance automatically becomes its administrator.
## Features
- Kanban board with drag-and-drop: reorder Categories, and drag Groups
between/within Categories
- Per-Group markdown notes and a to-do list with a completion progress
indicator
- Light/dark theme (follows system by default)
- Installable PWA (add-to-home-screen); requires a live connection to the
server for its database, so there's no offline mode
- Credentials-based accounts (email + password), with an Admin page to:
- change a user's role (Administrator / User / Pending), email, or
password, or delete their account
- control how the site handles new sign-ups (see [Sign-up modes](#sign-up-modes)
below)
## Tech stack
Next.js 16 (App Router) · React 19 · TypeScript · Tailwind CSS 4 ·
PostgreSQL via Prisma 7 · Auth.js v5 (Credentials provider, JWT sessions) ·
dnd-kit · base-ui
## Quick start (Docker)
This is the recommended way to run Organize. All you need is Docker with
the Compose plugin.
1. **Clone the repo**
```bash
git clone https://git.brianfertig.com/brianfertig/Organize.git
cd Organize
```
2. **Create your `.env`**
```bash
cp .env.example .env
```
Then open `.env` and:
- Generate a real `AUTH_SECRET` (used to sign session cookies) — for
example with `openssl rand -base64 32` — and paste it in.
- Optionally change `POSTGRES_PASSWORD` from the placeholder.
See [Configuration](#configuration) below for what each variable does.
3. **Start everything**
```bash
docker compose up -d
```
This builds the app image, starts Postgres, waits for it to be
healthy, then starts the app — which applies any pending database
migrations automatically on every boot before serving traffic. No
separate migration or setup step is needed.
4. **Open the app** at [http://localhost:3000](http://localhost:3000) (or
whatever `APP_PORT` you set) and sign up. The very first account
created becomes the site's administrator; everyone after that follows
whatever [sign-up mode](#sign-up-modes) is currently set (Open, by
default).
### Updating
```bash
git pull
docker compose up -d --build
```
`--build` matters here: without it, Compose will keep running whatever
image it already built and won't notice that the source changed.
### Stopping
```bash
docker compose down
```
Postgres's data lives in `./data/postgres` on the host (a bind mount, not
a Docker volume), so it survives `docker compose down` — back up that
directory if you want a safety net before major upgrades.
## Configuration
All configuration is via environment variables, read from `.env` by
Docker Compose (see `.env.example` for the template).
| Variable | Used by | Purpose |
| -------------------- | --------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `AUTH_SECRET` | `app` | Encrypts/signs session cookies. Required in production — generate with `openssl rand -base64 32`. |
| `POSTGRES_USER` | `db` | Postgres superuser created on first init. |
| `POSTGRES_PASSWORD` | `db` | Password for `POSTGRES_USER`. Change this from the `.env.example` placeholder. |
| `POSTGRES_DB` | `db` | Database name created on first init. |
| `APP_PORT` | `app` (host mapping only) | Host port the app is published on, e.g. `3000` for `http://localhost:3000`. Defaults to `3000` if unset. The container always listens on 3000 internally regardless of this value. |
| `DATABASE_URL` | host-side tooling only | Prisma connection string for running things like `npx prisma studio` from your own machine. **Not** used by the `app` container itself — see note below. |
> **Note on `DATABASE_URL`:** inside `docker-compose.yml`, the `app`
> service is given its own `DATABASE_URL` that points at the `db` service
> over the Compose network (`db:5432`), built from the `POSTGRES_*`
> variables — it ignores the `DATABASE_URL` in `.env`. The `.env` value
> (pointed at `localhost:5432`) is only there for convenience if you want
> to run Prisma commands, or the app itself, directly on the host. Since
> the bundled `db` service doesn't publish port 5432 to the host by
> default, that only works once you either add a `ports: ["5432:5432"]`
> mapping to the `db` service, or point `DATABASE_URL` at a Postgres
> instance you're running yourself.
## Sign-up modes
The Admin page (`/admin`, administrators only) has a "New sign-ups"
setting with four modes:
- **Open** (default) — anyone can sign up and immediately gets the `User`
role.
- **Approved** — anyone can sign up, but starts as `Pending` and can't log
in until an administrator changes their role to `User` or
`Administrator`.
- **Confirmed** — *not implemented yet* (shown disabled in the UI);
intended to gate new accounts on email confirmation instead of manual
approval.
- **Closed** — sign-ups are turned off entirely: the sign-up form and any
links to it are removed, and the sign-up action itself refuses new
accounts even if called directly.
The very first account on a fresh instance always becomes an
administrator, regardless of the current sign-up mode — otherwise there'd
be no one able to approve anyone.
## Local development (without Docker)
Running the app directly on your host is mainly useful for editing code
with hot reload. You'll still need a Postgres instance it can reach.
1. **Node 24** (matching the Docker image; no `engines` field enforces this, but it's what's tested) and `npm install`.
2. **A reachable Postgres.** The simplest option is to add a port mapping
to the `db` service in `docker-compose.yml` (`ports: ["5432:5432"]`)
and run just that service: `docker compose up -d db`. Then set
`DATABASE_URL` in `.env` to match (the `.env.example` default of
`postgresql://organize:organize@localhost:5432/organize` will work as-is
if you keep the default Postgres credentials).
3. **Apply migrations:**
```bash
npx prisma migrate dev
```
Against a fresh database this also runs `prisma/seed.ts` automatically,
creating `dev@example.com` / `password123` as an administrator with a
small sample board. If it doesn't (e.g. you'd already applied every
migration before), run `npx prisma db seed` to trigger it explicitly.
Don't run either against a database you care about.
4. **Run the dev server:**
```bash
npm run dev
```
Open [http://localhost:3000](http://localhost:3000).
Other useful scripts: `npm run build` (production build), `npm run start`
(serve a production build), `npm run lint`.
## Project structure
```
app/ Next.js App Router routes: (app) is the signed-in board + admin,
(auth) is login/signup
components/board/ The Kanban board: categories, groups, to-dos, drag-and-drop
components/admin/ Admin page: user table, role menu, sign-up mode settings
lib/actions/ Server Actions (auth, categories, groups, todos, notes, admin)
lib/ Shared server helpers (db client, auth helpers, settings, colors)
prisma/ Schema, migrations, and the dev-only seed script
auth.ts Auth.js configuration (Credentials provider, JWT session callbacks)
proxy.ts Route protection (redirects signed-out users to /login, etc.)
```