Files
mangaBookmark/docs/agents/issue-tracker.md
sulthan 08749df050 feat(backend)!: run on Postgres with a migration-owned schema (#28)
Swap modernc.org/sqlite for jackc/pgx/v5 with no observable change:
same endpoints, same wire format, same updated_at ordering rule.

The schema now comes from numbered SQL embedded in the binary and
applied on startup, one transaction each, recorded in
schema_migrations. That replaces two pieces of SQLite-era machinery,
both deleted rather than ported: the column probing (Postgres has ADD
COLUMN IF NOT EXISTS, and there is no legacy database left to probe)
and the Asura key rewrite, which has run clean on every start for
months now that the userscripts strip build hashes before writing. Its
regexp survives as latest.asuraBuildHash, where the poller still needs
it to scope chapter links to a series whose slug carries a rotating
hash.

Types get real: favorite is a boolean, chapter numbers double
precision, timestamps stay unix-ms bigint. SQLite's null-safe IS NOT
becomes IS DISTINCT FROM, which is what implements the rule that only
reading progress reorders a list. Inside COALESCE/NULLIF the status
and kind parameters need an explicit ::text -- there is no target
column to infer from and Postgres refuses to guess.

Tests lose their free t.TempDir() database, so Docker is now a hard
prerequisite for `go test ./...`: internal/pgtest starts one
postgres:17-alpine per test binary and hands each test a database of
its own.

Also lands CONTEXT.md and the four ADRs written while scoping #18.

BREAKING CHANGE: DB_PATH is retired for DATABASE_URL, which is
required and has no default. Compose gains a postgres service on an
internal network with its own volume; POSTGRES_PASSWORD joins .env.
The old bookmarks-data volume is deliberately left undeclared so
`docker compose down -v` cannot take the pre-migration database with
it. main is not deployable until #25 and #26 land.

Closes #20

Co-authored-by: Sulthan Zaki <sultankiki05@gmail.com>
Co-committed-by: Sulthan Zaki <sultankiki05@gmail.com>
2026-08-08 06:52:20 +07:00

3.5 KiB

Issue tracker: Gitea (tea CLI)

Issues and specs for this repo live as issues on the self-hosted Gitea instance gitea.violetcrown.my.id (repo sulthan/mangaBookmark). gh does not work here — use tea for everything past plain git. Auth lives in tea login, not a GH_TOKEN env var. tea infers the repo from the local clone's origin.

tea prints rendered boxes rather than plain text; pass --output json (or -o json) when a skill needs to parse the result.

Conventions

  • Create an issue: tea issue create --title "..." --description "..." (--labels, --assignees optional). Multi-line bodies: pass the body through a shell variable or heredoc.
  • Read an issue: tea issue <number> --comments (add -o json for machine-readable output).
  • List issues: tea issue list --state open -o json --fields index,title,body,labels,state,author; filter with --labels "...", --state open|closed|all, --assignee, --keyword.
  • Comment: tea comment <number> "..." (alias of tea comments add).
  • Apply / remove labels: tea issue edit <number> --add-labels "..." / --remove-labels "...". Labels must exist first — see tea labels list / tea labels create --name "..." --color "#rrggbb".
  • Close: tea issue close <number> (comment separately with tea comment; close takes no --comment flag).

Pull requests as a triage surface

PRs as a request surface: no. (Set to yes if this repo treats external PRs as feature requests; /triage reads this flag.)

When set to yes, PRs run through the same labels and states as issues, using the tea pr equivalents: tea pr <number> --comments, tea pr list --state open -o json, tea pr create --head <branch> --base main --title "..." --description "...", tea comment, tea pr close. Gitea shares one index space across issues and PRs, so a bare #42 may be either — resolve with tea pr 42 and fall back to tea issue 42.

When a skill says "publish to the issue tracker"

Create a Gitea issue with tea issue create.

When a skill says "fetch the relevant ticket"

Run tea issue <number> --comments.

Wayfinding operations

Used by /wayfinder. The map is a single issue; tickets are child issues.

  • Map: one issue labelled wayfinder:map holding the Notes / Decisions-so-far / Fog body. tea issue create --labels wayfinder:map --title "..." --description "...".
  • Child ticket: an issue labelled wayfinder:<type> (research/prototype/grilling/task) with Part of #<map> as the first body line, and a task-list entry in the map body. tea has no sub-issue command, so the task list plus the Part of line is the canonical link.
  • Blocking: a Blocked by: #<n>, #<n> line at the top of the child body. Gitea's native issue dependencies exist in the API but tea does not expose them; the body line is the source of truth. A ticket is unblocked when every listed blocker is closed.
  • Frontier query: tea issue list --state open -o json scoped to the map's task list; drop any ticket with an open blocker or an assignee; first in map order wins.
  • Claim: tea issue edit <n> --add-assignees <your-username> — the session's first write. (tea has no @me shorthand; use the Gitea username from tea login list.)
  • Resolve: tea comment <n> "<answer>", then tea issue close <n>, then append a context pointer to the map's Decisions-so-far via tea issue edit <map> --description "...".