From dc837a525409431073c0cdf334d92d4594a1a4aa Mon Sep 17 00:00:00 2001 From: Sam Chau Date: Tue, 27 Jan 2026 22:12:01 +1030 Subject: [PATCH] refactor(pcd): reorganize regularExpressions to CRUD pattern --- .gitignore | 3 ++ deno.lock | 8 +++ .../pcd/queries/regularExpressions/create.ts | 4 +- .../pcd/queries/regularExpressions/delete.ts | 6 +-- .../pcd/queries/regularExpressions/get.ts | 37 ------------- .../pcd/queries/regularExpressions/index.ts | 18 +++---- .../regularExpressions/{list.ts => read.ts} | 54 +++++++++++++------ .../pcd/queries/regularExpressions/types.ts | 17 ------ .../pcd/queries/regularExpressions/update.ts | 8 +-- src/lib/shared/pcd/display.ts | 27 ++++++++++ .../[databaseId]/+page.svelte | 8 +-- .../[databaseId]/views/CardView.svelte | 6 +-- .../[databaseId]/views/TableView.svelte | 20 +++---- 13 files changed, 111 insertions(+), 105 deletions(-) delete mode 100644 src/lib/server/pcd/queries/regularExpressions/get.ts rename src/lib/server/pcd/queries/regularExpressions/{list.ts => read.ts} (53%) delete mode 100644 src/lib/server/pcd/queries/regularExpressions/types.ts create mode 100644 src/lib/shared/pcd/display.ts diff --git a/.gitignore b/.gitignore index bcb6f28..6a41f5d 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,9 @@ node_modules CLAUDE.md .claudeignore +# Local TODO/planning docs +docs/todo/ + # Output .output .vercel diff --git a/deno.lock b/deno.lock index 4a4cd3f..1f27d2d 100644 --- a/deno.lock +++ b/deno.lock @@ -4,10 +4,12 @@ "jsr:@denosaurs/plug@^1.1.0": "1.1.0", "jsr:@felix/bcrypt@^1.0.8": "1.0.8", "jsr:@soapbox/kysely-deno-sqlite@^2.2.0": "2.2.0", + "jsr:@std/assert@1": "1.0.15", "jsr:@std/encoding@1": "1.0.10", "jsr:@std/fmt@1": "1.0.8", "jsr:@std/fs@1": "1.0.19", "jsr:@std/internal@^1.0.10": "1.0.12", + "jsr:@std/internal@^1.0.12": "1.0.12", "jsr:@std/internal@^1.0.9": "1.0.12", "jsr:@std/path@1": "1.1.2", "jsr:@std/path@^1.1.1": "1.1.2" @@ -31,6 +33,12 @@ "@soapbox/kysely-deno-sqlite@2.2.0": { "integrity": "668ec94600bc4b4d7bd618dd7ca65d4ef30ee61c46ffcb379b6f45203c08517a" }, + "@std/assert@1.0.15": { + "integrity": "d64018e951dbdfab9777335ecdb000c0b4e3df036984083be219ce5941e4703b", + "dependencies": [ + "jsr:@std/internal@^1.0.12" + ] + }, "@std/encoding@1.0.10": { "integrity": "8783c6384a2d13abd5e9e87a7ae0520a30e9f56aeeaa3bdf910a3eaaf5c811a1" }, diff --git a/src/lib/server/pcd/queries/regularExpressions/create.ts b/src/lib/server/pcd/queries/regularExpressions/create.ts index 2de2e97..288f595 100644 --- a/src/lib/server/pcd/queries/regularExpressions/create.ts +++ b/src/lib/server/pcd/queries/regularExpressions/create.ts @@ -5,7 +5,7 @@ import type { PCDCache } from '../../cache.ts'; import { writeOperation, type OperationLayer } from '../../writer.ts'; -export interface CreateRegularExpressionInput { +interface CreateRegularExpressionInput { name: string; pattern: string; tags: string[]; @@ -13,7 +13,7 @@ export interface CreateRegularExpressionInput { regex101Id: string | null; } -export interface CreateRegularExpressionOptions { +interface CreateRegularExpressionOptions { databaseId: number; cache: PCDCache; layer: OperationLayer; diff --git a/src/lib/server/pcd/queries/regularExpressions/delete.ts b/src/lib/server/pcd/queries/regularExpressions/delete.ts index 2e73482..4dfc683 100644 --- a/src/lib/server/pcd/queries/regularExpressions/delete.ts +++ b/src/lib/server/pcd/queries/regularExpressions/delete.ts @@ -4,14 +4,14 @@ import type { PCDCache } from '../../cache.ts'; import { writeOperation, type OperationLayer } from '../../writer.ts'; -import type { RegularExpressionTableRow } from './types.ts'; +import type { RegularExpressionWithTags } from '$shared/pcd/display.ts'; -export interface DeleteRegularExpressionOptions { +interface DeleteRegularExpressionOptions { databaseId: number; cache: PCDCache; layer: OperationLayer; /** The current regular expression data (for value guards) */ - current: RegularExpressionTableRow; + current: RegularExpressionWithTags; } /** diff --git a/src/lib/server/pcd/queries/regularExpressions/get.ts b/src/lib/server/pcd/queries/regularExpressions/get.ts deleted file mode 100644 index 5deb8d7..0000000 --- a/src/lib/server/pcd/queries/regularExpressions/get.ts +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Get a single regular expression by ID - */ - -import type { PCDCache } from '../../cache.ts'; -import type { RegularExpressionTableRow } from './types.ts'; - -/** - * Get a regular expression by ID with its tags - */ -export async function get(cache: PCDCache, id: number): Promise { - const db = cache.kb; - - // Get the regular expression - const regex = await db - .selectFrom('regular_expressions') - .select(['id', 'name', 'pattern', 'regex101_id', 'description', 'created_at', 'updated_at']) - .where('id', '=', id) - .executeTakeFirst(); - - if (!regex) { - return null; - } - - // Get tags for this regular expression - const tags = await db - .selectFrom('regular_expression_tags as ret') - .innerJoin('tags as t', 't.name', 'ret.tag_name') - .select(['t.name', 't.created_at']) - .where('ret.regular_expression_name', '=', regex.name) - .execute(); - - return { - ...regex, - tags - }; -} diff --git a/src/lib/server/pcd/queries/regularExpressions/index.ts b/src/lib/server/pcd/queries/regularExpressions/index.ts index c49fcff..bea0fb1 100644 --- a/src/lib/server/pcd/queries/regularExpressions/index.ts +++ b/src/lib/server/pcd/queries/regularExpressions/index.ts @@ -1,17 +1,15 @@ /** - * Regular Expression queries and mutations + * Regular Expression CRUD operations */ -// Export all types -export type { RegularExpressionTableRow } from './types.ts'; -export type { CreateRegularExpressionInput } from './create.ts'; -export type { UpdateRegularExpressionInput } from './update.ts'; +// Read +export { list, get } from './read.ts'; -// Export query functions -export { list } from './list.ts'; -export { get } from './get.ts'; - -// Export mutation functions +// Create export { create } from './create.ts'; + +// Update export { update } from './update.ts'; + +// Delete export { remove } from './delete.ts'; diff --git a/src/lib/server/pcd/queries/regularExpressions/list.ts b/src/lib/server/pcd/queries/regularExpressions/read.ts similarity index 53% rename from src/lib/server/pcd/queries/regularExpressions/list.ts rename to src/lib/server/pcd/queries/regularExpressions/read.ts index 21c368a..378ecb2 100644 --- a/src/lib/server/pcd/queries/regularExpressions/list.ts +++ b/src/lib/server/pcd/queries/regularExpressions/read.ts @@ -1,18 +1,17 @@ /** - * Regular expression list queries + * Regular expression read operations */ import type { PCDCache } from '../../cache.ts'; -import type { Tag } from '../../types.ts'; -import type { RegularExpressionTableRow } from './types.ts'; +import type { Tag, RegularExpressionWithTags } from '$shared/pcd/display.ts'; /** - * Get regular expressions with full data for table/card views + * List all regular expressions with tags */ -export async function list(cache: PCDCache): Promise { +export async function list(cache: PCDCache): Promise { const db = cache.kb; - // 1. Get all regular expressions + // Get all regular expressions const expressions = await db .selectFrom('regular_expressions') .select(['id', 'name', 'pattern', 'regex101_id', 'description', 'created_at', 'updated_at']) @@ -23,7 +22,7 @@ export async function list(cache: PCDCache): Promise e.name); - // 2. Get all tags for all expressions + // Get all tags for all expressions const allTags = await db .selectFrom('regular_expression_tags as ret') .innerJoin('tags as t', 't.name', 'ret.tag_name') @@ -47,13 +46,38 @@ export async function list(cache: PCDCache): Promise ({ - id: expression.id, - name: expression.name, - pattern: expression.pattern, - regex101_id: expression.regex101_id, - description: expression.description, - tags: tagsMap.get(expression.name) || [], - created_at: expression.created_at, - updated_at: expression.updated_at + ...expression, + tags: tagsMap.get(expression.name) || [] })); } + +/** + * Get a single regular expression by ID with tags + */ +export async function get(cache: PCDCache, id: number): Promise { + const db = cache.kb; + + // Get the regular expression + const regex = await db + .selectFrom('regular_expressions') + .select(['id', 'name', 'pattern', 'regex101_id', 'description', 'created_at', 'updated_at']) + .where('id', '=', id) + .executeTakeFirst(); + + if (!regex) { + return null; + } + + // Get tags for this regular expression + const tags = await db + .selectFrom('regular_expression_tags as ret') + .innerJoin('tags as t', 't.name', 'ret.tag_name') + .select(['t.name', 't.created_at']) + .where('ret.regular_expression_name', '=', regex.name) + .execute(); + + return { + ...regex, + tags + }; +} diff --git a/src/lib/server/pcd/queries/regularExpressions/types.ts b/src/lib/server/pcd/queries/regularExpressions/types.ts deleted file mode 100644 index 218a5a9..0000000 --- a/src/lib/server/pcd/queries/regularExpressions/types.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Regular Expression query-specific types - */ - -import type { Tag } from '../../types.ts'; - -/** Regular expression data for table/card views */ -export interface RegularExpressionTableRow { - id: number; - name: string; - pattern: string; - regex101_id: string | null; - description: string | null; - tags: Tag[]; - created_at: string; - updated_at: string; -} diff --git a/src/lib/server/pcd/queries/regularExpressions/update.ts b/src/lib/server/pcd/queries/regularExpressions/update.ts index a808d41..ab676d9 100644 --- a/src/lib/server/pcd/queries/regularExpressions/update.ts +++ b/src/lib/server/pcd/queries/regularExpressions/update.ts @@ -4,10 +4,10 @@ import type { PCDCache } from '../../cache.ts'; import { writeOperation, type OperationLayer } from '../../writer.ts'; -import type { RegularExpressionTableRow } from './types.ts'; +import type { RegularExpressionWithTags } from '$shared/pcd/display.ts'; import { logger } from '$logger/logger.ts'; -export interface UpdateRegularExpressionInput { +interface UpdateRegularExpressionInput { name: string; pattern: string; tags: string[]; @@ -15,12 +15,12 @@ export interface UpdateRegularExpressionInput { regex101Id: string | null; } -export interface UpdateRegularExpressionOptions { +interface UpdateRegularExpressionOptions { databaseId: number; cache: PCDCache; layer: OperationLayer; /** The current regular expression data (for value guards) */ - current: RegularExpressionTableRow; + current: RegularExpressionWithTags; /** The new values */ input: UpdateRegularExpressionInput; } diff --git a/src/lib/shared/pcd/display.ts b/src/lib/shared/pcd/display.ts new file mode 100644 index 0000000..5636b07 --- /dev/null +++ b/src/lib/shared/pcd/display.ts @@ -0,0 +1,27 @@ +/** + * PCD Display Types + * + * Types for query results that include JOINed data. + * These extend the generated Row types with related entities. + */ + +import type { RegularExpressionsRow } from './types.ts'; + +// ============================================================================ +// COMMON +// ============================================================================ + +/** Tag with metadata */ +export interface Tag { + name: string; + created_at: string; +} + +// ============================================================================ +// REGULAR EXPRESSIONS +// ============================================================================ + +/** Regular expression with tags (from JOIN) */ +export type RegularExpressionWithTags = RegularExpressionsRow & { + tags: Tag[]; +}; diff --git a/src/routes/regular-expressions/[databaseId]/+page.svelte b/src/routes/regular-expressions/[databaseId]/+page.svelte index 90f791e..41aabc7 100644 --- a/src/routes/regular-expressions/[databaseId]/+page.svelte +++ b/src/routes/regular-expressions/[databaseId]/+page.svelte @@ -14,7 +14,7 @@ import { browser } from '$app/environment'; import { Info, Plus, FileText, Users } from 'lucide-svelte'; import { goto } from '$app/navigation'; - import type { RegularExpressionTableRow } from '$pcd/queries/regularExpressions'; + import type { RegularExpressionWithTags } from '$shared/pcd/display'; import type { PageData } from './$types'; export let data: PageData; @@ -74,10 +74,10 @@ $: filtered = filterExpressions(data.regularExpressions, $debouncedQuery, searchOptions); function filterExpressions( - items: RegularExpressionTableRow[], + items: RegularExpressionWithTags[], query: string, options: typeof searchOptions - ): RegularExpressionTableRow[] { + ): RegularExpressionWithTags[] { if (!query) return items; const queryLower = query.toLowerCase(); @@ -89,7 +89,7 @@ // Search within tag names return item.tags.some((tag) => tag.name.toLowerCase().includes(queryLower)); } - const value = item[key as keyof RegularExpressionTableRow]; + const value = item[key as keyof RegularExpressionWithTags]; if (value == null) return false; return String(value).toLowerCase().includes(queryLower); }); diff --git a/src/routes/regular-expressions/[databaseId]/views/CardView.svelte b/src/routes/regular-expressions/[databaseId]/views/CardView.svelte index 8ffd2e1..3da0ac0 100644 --- a/src/routes/regular-expressions/[databaseId]/views/CardView.svelte +++ b/src/routes/regular-expressions/[databaseId]/views/CardView.svelte @@ -1,13 +1,13 @@