feat(database-design): add soft-delete query filters and helpers#104
Open
PAMulligan wants to merge 2 commits into
Open
feat(database-design): add soft-delete query filters and helpers#104PAMulligan wants to merge 2 commits into
PAMulligan wants to merge 2 commits into
Conversation
Implements the soft-delete pattern that pipeline.config.json enables by default (database.softDeleteDefault: true) but was previously unimplemented. - Add nullable deletedAt column to the shared users schema template - Add shared db/soft-delete.ts with notDeleted, withSoftDeleteFilter, softDelete, and restore helpers (generic over postgres-js and neon-http) - Add a node users route demonstrating DELETE -> softDelete and the ?include_deleted=true admin query param - Add tests asserting generated SQL for each helper - Document soft-delete column/helper/route generation in the database-design skill, gated on softDeleteDefault Closes #53 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
pipeline.config.jsonenables soft deletes by default (database.softDeleteDefault: true), but no middleware or query-filter implementation existed — generated projects got adeleted_atcolumn with no tooling to use it. This PR adds the full pattern to the templates and thedatabase-designskill.Changes
deletedAttimestamp added to the sharedusersschema template (null = active, timestamp = soft-deleted).shared/src/db/soft-delete.ts(new) — reusable helpers:notDeleted(table)→WHERE deleted_at IS NULLwithSoftDeleteFilter(table, includeDeleted, extra?)→ hides deleted rows unless?include_deleted=true, AND-ing in an optional extra clausesoftDelete(db, table, id)→ stampsdeletedAtinstead of deletingrestore(db, table, id)→ clearsdeletedAtPgDatabasequery-result and schema params, so it works with both the postgres-js (Node) and neon-http (Workers) clients with no casts on the query logic.node/src/routes/users.ts(new) — route handler pattern: list/get with?include_deleted=true,DELETE /:id→softDelete()(404 via.returning()), andPOST /:id/restore.shared/tests/soft-delete.test.ts(new) — asserts the exact SQL/params each helper produces via Drizzle's.toSQL()(no live DB required).database-designskill — new "Step 6.5 — Soft Delete Columns & Helpers" gated onsoftDeleteDefault; adds the column + index to the Users example, omitsdeletedAtfrom write validators, updates the Output table and Design Decisions.Acceptance criteria
deleted_atcolumn in the schema templateWHERE deleted_at IS NULLsoftDelete()that setsdeleted_atinstead of deletingsoftDelete()?include_deleted=trueadmin query paramdatabase-designskill generates soft-delete columns when enabledVerification
tsc --noEmitpasses for bothtsconfig.node.jsonandtsconfig.cloudflare.json(the CItypecheck-templatesjob).drizzle-orm@0.45.2— e.g.softDeleteemitsupdate "users" set "deleted_at" = $1 where "users"."id" = $2with[Date, id];restorepasses[null, id].Closes #53
🤖 Generated with Claude Code