docs: add usage, acceptance checklist and build workflow

This commit is contained in:
yyc12345 committed 2026-10-04 09:52:09 +08:00
1 parent 0fdd94d109
commit d8a4dd6190
4 files changed
+216 -2

No files matched your search

+56
View File
@@ -0,0 +1,56 @@
name: Build
# Manual trigger only. There is no push/pull_request trigger on purpose:
# the project must not depend on push-triggered CI.
on:
workflow_dispatch:
# Least privilege: the workflow only reads the repository and uploads artifacts.
permissions:
contents: read
jobs:
build:
name: ${{ matrix.rid }}
runs-on: ${{ matrix.os }}
strategy:
# One failing RID must not cancel the others.
fail-fast: false
matrix:
include:
- rid: win-x64
os: windows-latest
- rid: linux-x64
os: ubuntu-latest
- rid: osx-arm64
os: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.0.x
- name: Restore
run: dotnet restore YKanBan.slnx
- name: Build
run: dotnet build YKanBan.slnx -c Release --no-restore
# A failing test fails the job, so the publish and upload steps below are
# skipped and this RID produces no artifact.
- name: Test
run: dotnet test YKanBan.slnx -c Release --no-build --no-restore
- name: Publish
run: dotnet publish YKanBan/YKanBan.csproj -c Release -r ${{ matrix.rid }} --self-contained true -o publish/${{ matrix.rid }}
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: YKanBan-${{ matrix.rid }}
path: publish/${{ matrix.rid }}
if-no-files-found: error
+11 -2
View File
@@ -1,5 +1,14 @@
# YKanBan
My personal used local/offline kanban.
A personal, local/offline kanban board. Cross-platform desktop app built with Avalonia UI and MVVM. Each workspace stores its data in a `.ykanban` folder at the project root, Git-style.
WIP.
See [USAGE.md](USAGE.md) for workspaces, backups, the search syntax and command-line usage.
## Build and test
```
dotnet build YKanBan.slnx
dotnet test YKanBan.slnx
```
Packages are pinned in `YKanBan/YKanBan.csproj`.
+91
View File
@@ -0,0 +1,91 @@
# YKanBan Usage
YKanBan is a local/offline kanban board. It works like Git in one respect: all data for a managed project lives in a `.ykanban` folder at the project root, so the board travels with the project folder.
## 1. Workspace
- A **workspace** is a folder that directly contains a `.ykanban` directory. Only the given folder is checked; parent folders are never searched.
- `.ykanban` contains `ykanban.db` (the SQLite database with the board, cards and tags) and `ykanban.lock` (the exclusive lock file).
- A workspace is opened by exactly one YKanBan instance at a time. Opening the same workspace a second time shows the lock-conflict page.
### Command line
```
ykanban <path>
```
- `<path>` is the workspace folder to open.
- Starting without arguments, or with invalid arguments, shows the argument error page.
- If the path does not exist, the folder-missing page is shown.
- If the folder exists but has no `.ykanban`, the not-initialized page is shown with an **Initialize Workspace** button. Initializing creates the database and seeds the preset columns and tags in the current interface language.
## 2. Do not commit `.ykanban` to Git
`.ykanban` holds machine-local state and a lock file; it should not be committed. Add it to your **global** gitignore so it is ignored in every repository:
```
# ~/.gitignore_global (or %USERPROFILE%\.gitignore_global on Windows)
.ykanban/
```
Then enable the global ignore file once:
```
git config --global core.excludesFile ~/.gitignore_global
```
## 3. Backing up and migrating a workspace
The database runs in SQLite WAL mode. A workspace is therefore **three files**, not one: `ykanban.db`, `ykanban.db-wal` and `ykanban.db-shm`.
To back up or move a workspace, copy **all three files together** while YKanBan is closed. Copying only `ykanban.db` can lose the most recent changes.
## 4. Search syntax
The board search runs only when you press the search button (or press Enter in the search box); there is no live search. A blank query shows everything. The clear button (×) empties the box and restores the full board.
Search keywords (`AND`, `OR`) and qualifier keys are fixed English grammar and are **never localized**.
### 4.1 Grammar
```
query := orExpr
orExpr := andExpr ( OR andExpr )*
andExpr := operand ( (AND)? operand )* // adjacent terms are an implicit AND
operand := atom | '(' orExpr ')'
atom := word | phrase | qualifier
qualifier := key ':' (word | phrase)
key := tag | title | content | id | column
phrase := '"' any text '"' // escapes: \" to literal quote and \\ to literal backslash
```
### 4.2 Semantics
- `AND` (explicit or by adjacency) binds tighter than `OR`; parentheses force grouping.
- Only uppercase `AND` / `OR` are operators. Lowercase `and` / `or` are plain words. To search for the literal words `AND` or `OR`, quote them, for example `"AND"`.
- A bare word or phrase matches a **substring of the title OR the content**.
- `tag:NAME` matches a tag by its **exact** name.
- `column:TITLE` matches a column by its **exact** title.
- `title:TEXT` matches a substring of the card title, and `content:TEXT` matches a substring of the card content.
- `id:N` matches a card by its **exact** numeric id.
- All matching is case-insensitive (SQLite ASCII semantics).
- Quotes allow values with spaces, for example `tag:"release notes"` or `column:"In Progress"`.
- Inside a phrase, `\"` produces a literal quote and `\\` a literal backslash.
### 4.3 Strict validation
An invalid expression opens a modal error dialog and **does not run the search**. The error dialog is centered on the parent window; its text is a localized "query expression is invalid" message plus the parser's non-localized English detail. After closing it, the search box keeps what you typed and the board keeps the previous results.
The following are invalid:
- unbalanced parentheses, for example `(a` or `a)`;
- a dangling operator, for example `bug AND`;
- consecutive operators, for example `a AND OR b`;
- a qualifier without a value, for example `tag:`;
- an unterminated phrase, for example `"abc`;
- an invalid escape inside a phrase (a backslash not followed by `"` or `\`), for example `tag:"a\x"`;
- an unknown qualifier key. Only `tag`, `title`, `content`, `id` and `column` are valid, and the key is case-sensitive, so `Tag:x` is an error. A word whose colon is not preceded by an identifier (for example `:foo`) is treated as plain text.
## 5. Export
The **Export** button writes a human-readable Markdown snapshot of the whole board (columns, cards and the tag table) to a file you choose. The suggested file name and the timestamps in the document follow the current interface language. The export is read-only; there is no import.
+58
View File
@@ -0,0 +1,58 @@
# Manual acceptance checklist
Everything here is verified by hand on the local Windows build. Automated tests cover storage, the search parser/compiler and the export; the UI is verified manually.
## Startup and workspace
- [ ] `ykanban <path>` with a valid workspace opens the board.
- [ ] `ykanban` with no arguments shows the argument error page.
- [ ] `ykanban a b` (more than one argument) shows the argument error page.
- [ ] A path that does not exist shows the folder-missing page.
- [ ] An existing folder without `.ykanban` shows the not-initialized page with an **Initialize Workspace** button; after clicking it the board opens with the preset columns and tags.
- [ ] Opening the same workspace in a second instance shows the lock-conflict page; closing the first instance lets the second open.
- [ ] The window title is `<workspace name> - YKanBan`, or just `YKanBan` on an error page.
## Language
- [ ] A new workspace is seeded with columns and tags in the language active at creation time.
- [ ] Switching the language in Settings shows the "takes effect after restart" notice and the change only applies after a restart (restart-effective item).
- [ ] After restarting in Chinese, the whole UI is Chinese.
## Theme
- [ ] Settings offers light / dark / follow system; switching applies immediately and the interface recolors completely (theme three-state item).
- [ ] Cancelling Settings keeps the previous theme; accepting keeps the chosen one.
- [ ] Custom surfaces (top bar, columns, cards, error text) recolor with the theme.
- [ ] Tag colors always show their raw `#RRGGBB` value in both themes.
## Board
- [ ] Columns run left to right and cards top to bottom; there is no drag.
- [ ] A card shows the bold `#id` with its title (or just `#id` when untitled), a truncated content preview and colored tag badges; no timestamps.
- [ ] Clicking a card body opens the editor; the card menu opens in place.
- [ ] Add, edit and delete a column and a card; deletes honor the confirmation toggles.
- [ ] The column editor rejects an empty or duplicate title with an inline error.
- [ ] Editing a card with no effective change writes nothing; cancelling writes nothing; closing with unsaved changes asks to discard when that toggle is on.
- [ ] Tag assignment in the card editor adds existing tags and removes them with the ×; the picker only offers tags not already assigned.
- [ ] Move a card to another column; with only one column the picker reports there is nowhere to move.
- [ ] The Display flyout changes column width (narrow/standard/wide/custom) and card/column sort immediately.
## Search
- [ ] Pressing the search button and pressing Enter in the search box behave the same.
- [ ] A blank query shows everything; the clear button restores the full board.
- [ ] A valid query filters cards while keeping every column (empty columns stay visible).
- [ ] The filter status icon is dimmed when not filtering and solid while filtering, and its tooltip states the current status.
- [ ] An invalid query opens the error dialog with the localized message plus the English detail; after closing, the typed text and the previous results remain.
- [ ] Search state persists while switching tabs.
## Tags
- [ ] The tag tab lists color, name, description and usage count.
- [ ] Add, rename, recolor (with the color picker) and re-describe a tag; the board refreshes after a change.
- [ ] Deleting a tag warns that it will be removed from N cards and honors the confirmation toggle.
## Export
- [ ] Export prompts for a file with a language-appropriate default name and writes Markdown with language-appropriate timestamps, matching the current interface language (export-language-follows-UI item).
- [ ] After a successful export a confirmation dialog shows the written path.