feat: add ticket numbers to cards with workspace prefix (#443)

* feat: add ticket numbers to cards with workspace prefix

- Add cardNumber to cards
- Add cardPrefix/cardCounter to workspace
- Populate initial prefixes and numbers via new migration
- Introduce generateWorkspacePrefix util and export it
- Include cardNumber in card-related API responses and search results
- Render and display tickets as PREFIX-NUMBER in UI
- Update Card component to accept ticketNumber
- Update CardModal and board cards to show number when available
- Add cardNumber to CommandPalette search results type

* feat: regen migration

* feat: enhance card and workspace schemas with cardNumber and indexing

- Updated the card repository to allocate card numbers atomically per workspace.
- Modified the card schema to include a cardNumber field and added an index on listId and cardNumber for improved query performance.
- Enhanced the workspace schema to include an index on cardPrefix for optimized lookups.
- Adjusted the migration journal to reflect the new schema changes and their timestamps.
- Updated the regex in workspace repository to allow alphanumeric prefixes in ticket IDs.

---------

Co-authored-by: Henry <henry_ball@hotmail.co.uk>
This commit is contained in:
Florent Azonnoudo
2026-04-28 21:29:41 +00:00
committed by GitHub
parent bc8b5463b3
commit 4658b2961c
21 changed files with 4302 additions and 91 deletions

View File

@@ -0,0 +1,26 @@
export const generateWorkspacePrefix = (name: string): string => {
const words = name
.trim()
.split(/\s+/)
.filter((w) => w.length > 0);
if (words.length === 0) return "WS";
const firstWord = words[0];
if (words.length === 1 && firstWord) {
const word = firstWord.replace(/[^a-zA-Z0-9]/g, "").toUpperCase();
return word.slice(0, 3) || "WS";
}
const initials = words
.map((w) => {
const cleaned = w.replace(/[^a-zA-Z0-9]/g, "");
return cleaned.length > 0 ? cleaned[0]! : "";
})
.filter((c) => c.length > 0)
.join("")
.toUpperCase()
.slice(0, 4);
return initials || "WS";
};

View File

@@ -1,5 +1,6 @@
export * from "./generateUID";
export * from "./generateSlug";
export * from "./generateWorkspacePrefix";
export * from "./subscriptions";
export * from "./email";
export * from "./dueDateFilters";