# Changelog Versions follow [semver](https://semver.org). From 1.0 on, upgrades within 1.x never break your data, backups or automation (see [docs/UPGRADING.md](docs/UPGRADING.md#what-10-promises)). The version is shown in **Settings**, in the container log on start, and in every backup export. ## 1.5.0: Teams foundation - **Teams, off by default.** The team features below (assignees, Mine and Unassigned, watching, @mentions, the bell, personal notifications and names in the history) are behind **Settings → General → Teams**. It's off until an admin turns it on (installs that already have several people keep it on), so a solo install looks as it did before. Turning it off hides them and deletes nothing; turning it back on brings everything back. See [docs/USING.md](docs/USING.md#teams). - New tickets from the submit page still ring the bell for admins while Teams is off (the bell shows while the submit page is on). With Teams on, they're an event of their own under **Account → Notifications**, in the app for admins by default. - **People.** Belltower now has accounts, each one an admin or a member. - **Admins** run the install: people, settings, notification channels, the submit page, backups and restore. - **Members** do all the board work, and manage their own profile, password and API tokens. - **Settings → People** adds someone with a temporary password, changes roles and display names, and deactivates or re-enables people. The owner is always an admin. - **Account**, in the ☰ menu, holds your profile, password, API tokens, single sign-on and notification choices. - **Who did what.** Every history entry and work-log note shows who made it, including "via API token" and the submit page. - Only the note's author or an admin can edit or retract a note. - Retracting and restoring a note are recorded too. - **Assignees.** A card can have one assignee. Pick them on the card, see their initials on the tile, and filter the board by assignee. - **Mine** lists your open cards. - **Unassigned** lists every open card nobody has taken, most urgent first, with **Take it**. If two people grab the same card at once, the second is told who got it. - On phones the top bar shows icons only, and Calendar and Recurring moved into the ☰ menu. - **Watching, @mentions and the bell.** - **Watch** a card to hear about new notes, moves and changes of assignee. You watch a card automatically when you create it, are assigned it, are mentioned on it or write a note on it. - Type `@` in a note to mention someone. - The bell in the top bar lists your notifications. It can play a sound on each device (**Settings → Appearance**). - **Personal notifications.** **Account → Notifications** chooses, for each kind of event, the bell, a Discord ping in the install's channel, or your own ntfy topic. See [docs/NOTIFICATIONS.md](docs/NOTIFICATIONS.md#personal-notifications). - **Tag-restricted accounts.** In **Settings → People**, an admin can restrict a member to certain tags. They then see only tickets that carry one of those tags, everywhere: board, search, calendar, history, the bell, their own notifications and their API tokens. Untagged tickets are hidden from them, and with no tags left they see nothing. See [docs/USING.md](docs/USING.md). - Cards they create get their tags, and they can't manage tags, columns, board-wide actions or recurring templates. - A ticket can't be assigned to someone who can't see it. Retagging a ticket, or narrowing someone's tags, unassigns them from tickets they can no longer see, and the history says so. - Admins and the owner can't be restricted. It works whether Teams is on or off. - **Request types label their tickets.** Each request type on the submit page has a list of labels that go on every ticket filed with it, so tickets can land straight with the right tag (and the people restricted to it). Submitters no longer pick tags. See [docs/SUBMIT-PAGE.md](docs/SUBMIT-PAGE.md). - **The board keeps itself up to date.** While the tab is visible, the board, lists, calendar and the open card refresh every 15 seconds, and a new ticket now lands on the board together with the bell's chime. These refreshes don't keep an idle tab signed in. If someone changes a card's title while you're editing it, you're told before your save replaces it. - **Single sign-on (optional).** Sign in through Authentik, Authelia or another OpenID Connect provider. See [docs/SSO.md](docs/SSO.md). - With single sign-on on, the login page shows the sign-on button and keeps the password form behind a **Sign in with a password** link. **Settings → Single sign-on** can show the form again, or turn password sign-in off for everyone but the owner, who can still use it at `/login?password`. `APP_PASSWORD` still resets the owner. - With a required group set, Belltower also asks for the `groups` scope when the provider offers one (VoidAuth and Pocket ID send groups only then), and the log says why someone failed the group check. - **API tokens belong to a person.** Members see their own under **Account**, and admins see everyone's under **Settings → Automation**. A token stops working while its owner is deactivated. The automation API itself hasn't changed. - **Upgrading.** There's nothing to do, and nobody is signed out. - Teams starts off, so the board looks as it did in 1.4 until an admin turns it on (installs that already have several people keep it on). - Your password becomes the owner account `admin`. The name `tower-tracker` that password managers saved still works. - Signed-in devices and API tokens move to the owner. - `APP_PASSWORD` now sets the owner's password only, and "set it and restart" still gets you back in. - Backups now include people, but never their passwords. Restoring keeps the accounts of the install you restore into, and backups from every earlier version still restore. - Each request type keeps its "Always add the label" as its one label. The lists of tags submitters could pick are dropped; add any you still want to the type's labels. - Nobody is restricted to tags until an admin sets it. - If you already use single sign-on, the password form moves behind a link on the login page. Nothing else changes until an admin turns password sign-in off. - The database moves to layout 11. Going back to 1.4 means putting back the copy saved before the upgrade, and any accounts created since are lost (see [docs/UPGRADING.md](docs/UPGRADING.md#upgrading-to-15-people)). - **From a 1.5.0 release candidate (rc.1 to rc.3):** the same notes apply; the database moves from layout 9 to 11. ## 1.4.0: Not every check passes - **Checklist marks.** Clicking a checklist item now cycles through three marks, then back to empty: ✓ done, ✗ failed (or "no" to a yes/no question), and ~ couldn't verify or still in progress. - ✓ and ✗ both count toward progress. The card's progress bar shows ✓ in green and ✗ in red. - On the board, a ticket's checklist badge turns red when any item failed and yellow when any couldn't be verified, so a failure doesn't hide behind "5/5". - Clicking through several marks quickly records only the one you stop on in the history. - **Upgrading.** Items checked before 1.4 show as ✓, the automation API hasn't changed, and backups from every earlier version restore. The database moves to layout 8, so going back to 1.3 means putting back the copy saved before the upgrade (see [docs/UPGRADING.md](docs/UPGRADING.md#if-something-goes-wrong)). ## 1.3.0: Keeping everyone in the loop - **Status links for people who file tickets.** After sending a ticket from the submit page, people get a link they can bookmark. It opens a page, no sign-in needed, with the ticket's title and number, when it was sent and last moved, and whether it's received, being worked on, waiting on something or done. Once it's done, the page also shows the resolution reason. Descriptions, notes and work logs stay private. - **Status link** on any ticket copies its link, so you can also send one to someone who told you in person. - **Settings → Submit page → Reset status links** cuts off every link handed out so far. See [docs/SUBMIT-PAGE.md](docs/SUBMIT-PAGE.md#status-links). - **Seen this before?** An open ticket lists up to five finished tickets that look like it, archived ones included. Each shows the resolution reason and the start of the note, so last time's fix is right there. **Link** links one as related. **Add ticket** shows up to three matches under the title once it has two words. - **ntfy, Gotify and webhooks.** Notifications can now go to ntfy, Gotify or any webhook, as well as Discord. - Each channel picks its own events. For example, everything can go to Discord and only urgent tickets to your phone. - Webhooks get a versioned JSON body that can be signed with a secret. See [docs/NOTIFICATIONS.md](docs/NOTIFICATIONS.md#webhook). - Discord sends the same messages as before. - **Ticket counts on your dashboard.** `GET /api/v1/summary` gives counts for Homepage, Home Assistant and similar dashboards: open tickets by state, urgent, overdue, finished today and in the last 7 days, and more. - It uses a new kind of API token that can only read those counts. - **Settings → Automation** shows a ready-to-paste Homepage and Home Assistant setup for it. See [docs/AUTOMATION.md](docs/AUTOMATION.md#dashboards). - **Fixes:** - A daily summary that fails to send now waits 30 minutes before trying again. Before, it retried every minute for the rest of the day. - Deleting the column the submit page files into could let a new column quietly receive submissions. The setting is now cleared along with the column. - **Upgrading.** Existing API tokens keep doing everything they did, and backups from every earlier version restore. The database moves to layout 7, so going back to 1.2 means putting back the copy saved before the upgrade (see [docs/UPGRADING.md](docs/UPGRADING.md#if-something-goes-wrong)). ## 1.2.3: Housekeeping The app itself hasn't changed. This release tidies up around it. - **Try it without installing.** The [live demo](https://bernie-sandler.github.io/Belltower/) runs the real app in your browser with a sample board, and your changes stay in that browser. **View as Submitter** shows the submit page. - **Screenshots in the README**, in light and dark to match your GitHub theme. - **Shorter docs.** The upgrade notes for betas and for coming from Tower Tracker are gone, since releases before 1.2.1 are no longer published. The original design proposal (`docs/DESIGN.md`) is retired; the reasons behind the stack now live in [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md). The README no longer calls Belltower early development. - **Release workflow.** The old `beta` channel is gone. Releases are `latest` (and `1`, `1.2`, `1.2.3`) or `rc`. ## 1.2.2: The real icon in the app - **The top bar and sign-in page show the real Belltower icon.** They were drawing a plain bell in code, so they didn't match the Home Screen icon. They now use the same picture, the bell in its tower, from the app's icon files. ## 1.2.1: Compose file uses the new image The app itself hasn't changed. This release makes the files that ship with a release match the new image address. - **The right image out of the box.** `docker-compose.yml` now uses `ghcr.io/bernie-sandler/belltower`. The copy in the 1.2.0 release still named the old address. - **Older versions are retired.** Images now go back to 1.2.0, and `ghcr.io/bernie-sandler/tower-tracker` and the earlier releases are going away. If `TT_VERSION` is set to `rc`, `beta` or anything before 1.2.0, change it to `latest`. Your data is safe either way: 1.2.1 reads every older database and backup. ## 1.2.0: Tower Tracker is now Belltower - **New name, new look.** The app is now Belltower, with a new logo and icons. That covers the top bar, sign-in page, browser tab, Home Screen app, Discord messages, backup file names, the Docker container and the docs. - **Your data stays put.** The database, backups, API tokens, sign-ins and the automation API (`/api/v1`) are unchanged. Backups made under the old name restore as usual, and saved import prompts still work. - **One manual step for existing installs.** The Docker container and stack have a new name, so stop the old one first and keep your `DATA_PATH`. - **New image address.** The repository is now `bernie-sandler/Belltower` and the image is `ghcr.io/bernie-sandler/belltower`. `docker-compose.yml` and the Unraid template point there. Versions before 1.2.0 stay at `ghcr.io/bernie-sandler/tower-tracker`, so if `TT_VERSION` is set to one of those, or to `rc` or `beta`, change it to `latest`. ## 1.1.0: Drag whole folders - **Move a folder in one go.** Tickets whose work card is in another column sit under a folder header. Drag that header to another column and all its tickets go with it: with the mouse, a long press on a phone, or `Space` and the left and right arrow keys. A click still folds it, and a folded folder brings its hidden tickets along. - **All or nothing.** A folder moves as one step, so a failure can't leave it split between columns. If a ticket is blocked, or went to the Trash on another device, nothing moves and a message names the ticket. - **Nothing to do when upgrading.** The database, backups and the automation API (`/api/v1`) are unchanged. The web app gets one new route of its own, `POST /api/cards/move-many`. ## 1.0.0: Stable 1.0 adds no new features. It's 0.10 made trustworthy for the long run, and it ran as a release candidate on a real server first. - **Promises from here on:** every 1.x reads every older database and backup; database changes only add; the automation API (`/api/v1`) is frozen; breaking changes wait for 2.0. - **Upgrade tested.** Every older schema is now tested on every build, both upgraded in place and restored from a backup. Before release, real data from 0.5, 0.6, 0.7, 0.9 and 0.10 was upgraded and restored into 1.0, along with real snapshots. - **Faster boards when Done grows.** The Done column shows the 50 most recently finished cards, with **Show N older cards** for the rest. A board with 1,900 finished cards went from about 50,000 page elements to 5,000, and renders roughly eight times faster. - **Contrast.** Secondary text in the dark theme is a little lighter, so every screen passes the 4.5:1 contrast check in both themes. - **Documentation rewritten.** The README is now a short overview. Each topic has its own page under `docs/` (install, upgrading, using it, remote access, backups, submit page, notifications, automation, Claude drafting), plus two frozen specs: the [automation API](docs/API-V1.md) and the [backup format](docs/BACKUP-FORMAT.md). - **Stable by default.** `docker-compose.yml` and `.env.example` now use `latest`. If your `.env` says `beta` or `rc`, change it to `latest`, because neither of those follows 1.0. - **More ways to set it up on Unraid.** There's now a template for Unraid's **Add Container** form ([docs/INSTALL.md](docs/INSTALL.md)), and step-by-step setup for turning Unraid's alerts into tickets ([docs/AUTOMATION.md](docs/AUTOMATION.md)). - **MIT license.** See [LICENSE](LICENSE). - **For developers:** `npm run seed:perf -w @tt/server -- ` creates a 2,000-card board and times it; new tests cover keyboard moves with screen-reader announcements and the `/api/v1` contract. **Known gap:** Claude drafting is tested against a stand-in for Claude, but hasn't been run against the live API yet. It's optional and stays off without an API key. If a draft fails, the dialog says so and you can fill the ticket in by hand. ## 0.10.0: Resolutions, light theme, smarter Claude (beta) - **Resolution notes.** **Mark done** opens a quick dialog: how it was resolved (Fixed, Won't fix, Duplicate, Can't reproduce, No longer needed) and an optional note. The first reason is preselected and Enter accepts. - Dragging a card into Done (or Move to → Done) shows a toast with **Add resolution**. - Done cards show a **Resolution** section, editable any time. Reopening a card clears it; the history keeps every version. - Tiles show a badge when the reason isn't the default ("Won't fix", "Duplicate"…). - Resolution notes are searchable ("how did I fix this last time?"). - The reasons are an editable list in **Settings → Resolution reasons**; the first is the default. - Automation recoveries that complete a ticket record the default reason with a "Recovered" note. - Card import accepts `resolution` and `resolutionNote` for cards created in Done. - **Light theme.** Follows your device's light/dark setting by default. **Settings → Appearance** picks Light, Dark or System, remembered per device. - **Claude drafting knows your board.** - A draft now suggests the card type (ticket or work card), an open work card to file it under, and links to open cards it blocks, waits on or relates to, each with a reason. All of it shows in the review form and can be changed or removed. - New **Add ticket → Describe several issues**: paste notes, a to-do list or logs, and Claude splits them into cards (grouping steps under a work card, with links between them). You review the same preview as an import, then create them all at once. Counts as one draft. - Drafts now also send your open cards' titles (up to 100) to Anthropic, so Claude can refer to them. - Database schema 6 (`cards.resolution`, `cards.resolution_md`). ## 0.9.0: Tickets from other people and services (beta) - **Settings page** (Menu → Settings): - ticket number format (e.g. `TT-{YYYY}{MM}{DD}-{N}`); - the app's address; - Claude model; - blocked column; - submit page, automation tokens, Discord, password. - **Submit page.** A shareable link (`/submit/`) where people without your password file tickets. They pick a request type and answer its questions; the answers are appended to their description, and the title follows the type's pattern ("Plex – {title} – {summary}"). Also tags you allow, up to 3 screenshots, and their name. - Starts with **General**, **Plex** and **Game servers**, based on your Discord support templates. - Request types and their questions (short or long text, pick one or several, date and time, yes/no) are editable in Settings. - Rate limited, image-only screenshots, a bot trap, and a new link at any time. - **Automation.** API tokens and `POST /api/v1/cards`, with `dedupeKey` (repeat alerts add a note to the open ticket) and `"event": "resolved"` (notes the recovery, and can mark it done). Includes an Uptime Kuma webhook (`/api/v1/hooks/uptime-kuma`). Recipes in `docs/AUTOMATION.md`. - **Discord notifications** through a webhook: - new tickets from the submit page or automation; - blocked cards; - a daily summary of overdue and due-today cards; - urgent cards: created urgent or raised to urgent later. "Urgent" defaults to P0–P1 or S1 and can be changed; - a **Send test** button, **Send summary now**, and the last delivery result. - Database schema 5 (`request_types`, `api_tokens`), included in backups. ## 0.8.0: Hardening (beta) No new features; this release is about upgrading and releasing safely. - **Safer upgrades.** Before the database is upgraded, the app saves a copy of it in `/data/backups` (`pre-migrate-v-to-v-….db`, last 5 kept). If the copy can't be written, nothing is changed and the container stops with an error explaining why. - **Prebuilt images.** Tagged releases are published to `ghcr.io/bernie-sandler/tower-tracker` by GitHub Actions. `docker-compose.yml` now pulls the image (`TT_VERSION` in `.env`, default `beta`); building from source is still possible with `docker-compose.build.yml`. Updating is `docker compose pull && docker compose up -d`. - **Tests.** Web unit tests (board grouping, filters, the Add ticket form, history text, Mark done dialog) and end-to-end tests in Chrome at desktop and iPhone sizes (login, cards, dragging, blocked cards, links, work cards, import, backup and restore, search). GitHub Actions runs everything on every push, plus a Docker build and health check. - **Security.** Updated zod, fastify and fast-uri for published advisories (`npm audit` is clean). Dependabot opens weekly update PRs. New `SECURITY.md`. - Fixed: after **Add item** in the Add ticket checklist, the first letters typed could be lost. - The link picker and the work-card picker are now one component. ## 0.7.0: Work cards - Two card types: **tickets** (an issue or finding) and **work cards** (what you're actually working on). Work cards have a purple accent and a "Work 2/3" badge counting their finished tickets. Switch type in the card. - File tickets under a work card (**Part of** in the ticket, or **Add ticket here** / **File a ticket…** in the work card). One level only; a work card can't be part of another card. - On the board, a work card's tickets stack together in every column, indented under the work card, or under a "▾ 261027-1 Plex upgrade" header when the work card is in another column. Groups collapse; that's remembered per browser. - **Mark done** on a work card with open tickets asks: **Complete with N tickets** or **Only this card**. All or nothing: if any ticket is blocked by an open card outside the group, nothing moves and the stuck tickets are listed. Dragging a work card into Done offers to complete its tickets from the toast. - A trashed or archived work card stops grouping its tickets until it's restored. - Board filter **Type** (Work cards / Tickets). Add ticket has Type and Part of fields. - Card import: `"type": "work"`, nested `"tickets": [...]`, and `"partOf"` (a ticket number, or a `"ref"`/title in the same import). The preview shows the tree, and **Copy AI prompt** lists your open work cards. - Card import links: `"blocks"`, `"blockedBy"` and `"relatedTo"` by ticket number or by `"ref"`/title within the import. Same rules as links made by hand (blocked cards move to Blocked/Waiting; no blocking a done card). - API: `kind`/`parentId` on cards, `POST /api/cards/:id/complete`, `GET /api/cards?kind=`. Database schema 4. ## 0.6.0: Ticket numbers - Every card gets a ticket number when it's created, shown with its title as **"261024-1 — Title"** on the board, in the card, in links, search, the calendar, Archive and Trash. - The format is `YYMMDD-N`: the local creation date (app time zone) and a counter that starts at 1 each day. Numbers never change when the title is edited and are never reused. - Existing cards are numbered by their creation date on the first start of 0.6.0 (and when restoring an older backup). - Search and the link picker find cards by ticket number. - Database schema 3 (`cards.ticket_no`). ## 0.5.1: Blocking links are enforced - A card that's **blocked by** open cards can't be completed: moving it into Done (drag and drop, Move to…, Mark done, or deleting its column into Done) is refused with the names of the open blockers (`409 blocked`). It can still move between other columns. - A blocker counts as finished once it's done (or archived after being done); blockers in the Trash are ignored. - An open card can't be added as a blocker of a card that's already done. - When a card becomes blocked (linked as "blocked by" an open card, or a blocker is reopened or restored from the Trash), it moves to the **Blocked/Waiting** column automatically, and its history says which cards block it. Choose a different column, or turn this off, with **Move blocked cards here** in a column's menu. The blocked column shows a ⊘ icon. Done cards and cards already in that column don't move. - Blocked cards show a **Blocked** badge on the board, and the card's Linked cards section says what it's waiting on. Cards and the board refresh when a blocker is finished, reopened, trashed or restored. ## 0.5.0: Add ticket with Claude drafting - **Add ticket** button in the top bar (`Shift+N`). - **Describe the issue**: Claude drafts the ticket (title, Markdown details, priority from impact × urgency, severity, labels, checklist) for you to review before it's created. - **Blank ticket**: the same form, filled in by hand. - Optional `ANTHROPIC_API_KEY` (and `ANTHROPIC_MODEL`, default `claude-opus-5-5`). Without a key the app stays fully offline and Add ticket offers the paste-JSON import instead. - New API: `GET /api/ai/status`, `POST /api/ai/draft`, `POST /api/tickets`. ## 0.4.0: Backup & restore, card import (tag `alpha-phase-4`) - Export to JSON or ZIP (with attachments), staged restore with preview and `RESTORE` confirmation. - Nightly database snapshots (last 7 kept). - AI-friendly card import (`tower-tracker/cards@1`). - Full README. ## 0.3.0: Calendar, search, recurring maintenance (tag `alpha-phase-3`) - Month and week calendar. - Full-text search, including archived cards. - Board filters. - Recurring maintenance templates. ## 0.2.0: Card detail (tag `alpha-phase-2`) - Markdown descriptions, checklists, attachments, links between cards. - Work log with backdating and edit history. - Archive and Trash. - Priority P0–P3 and severity S1–S4. ## 0.1.0: First release - Docker container, password auth, board with columns, cards, drag and drop, labels.