@tristan2828/ui-foundation 4.2.1 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -437,7 +437,8 @@ is a filled-in example while the Widgets demo is still here).
437
437
  each value as its cell shows it), plus the sparse record showing its
438
438
  "not set" labels and no blank value. Its flows: the table's title link
439
439
  opens it, saving and cancelling the form return to it, creating opens
440
- the new record's view, and Delete confirms then lands on the list.
440
+ the new record's view, and Delete confirms then lands on the list
441
+ (a soft-deleted entity's toast also has an Undo that restores it).
441
442
  Each quick action gets its own tests (copy `quick action: …` in
442
443
  `e2e/widget-view.spec.ts`): the change shows and the PATCH carries it
443
444
  (a list item sends the whole list), a server-side effect shows once the
@@ -518,3 +519,34 @@ is a filled-in example while the Widgets demo is still here).
518
519
  capability they don't have (a new field-type widget, say), don't copy
519
520
  one into `src/` to change it: raise it for the foundation (AGENTS.md
520
521
  "Changing the Foundation") and build the screen once the release ships.
522
+
523
+ ## Deleting
524
+
525
+ The plan's "Deleting" line says which of three. The Widget reference is the
526
+ soft one; copy it.
527
+
528
+ - **Retired by a status:** no delete endpoint, screen or action. The
529
+ status field and its filter do the job.
530
+ - **Soft-deleted:**
531
+ - *Model and migration:* a nullable `deleted_at timestamptz`, commented
532
+ in the migration (null means live; set by DELETE, cleared by restore).
533
+ It is never on the wire. `backend/app/models.py`,
534
+ `migrations/versions/0012_widget_soft_delete.py`.
535
+ - *Router:* `DELETE /<entity>/{id}` sets `deleted_at`; `POST
536
+ /<entity>/{id}/restore` clears it and returns the record (404 unless
537
+ it is deleted); the list leaves deleted records out unless asked
538
+ (`deleted=true` lists only them); get and update of a deleted record
539
+ are a 404. `backend/app/routers/widgets.py` (`_get_or_404`'s
540
+ `deleted` flag).
541
+ - *Contract, gateway, mocks:* `restore<Entity>` in `openapi.yaml`, the
542
+ gateway's `restore<Entity>`, a `useRestore<Entity>Mutation`, and mocks
543
+ that move the record aside (`deletedWidgets` in `src/mocks/data.ts`).
544
+ - *Screens:* the delete dialog says it can be undone, and the success
545
+ toast carries an Undo that restores (`delete-widget-action.tsx`).
546
+ - *MCP:* give the entity's `McpEntity` `delete` and `restore` (and add
547
+ `deleted` to its filters). Chats then get `delete(url)`, marked
548
+ destructive so the chat asks before each call, and `restore(url)`.
549
+ Both are logged with the whole record.
550
+ - **Hard-deleted:** `DELETE` removes the row. Give the entity no `delete`
551
+ in `mcp_entities.py`: a chat that read planted instructions would
552
+ destroy data that only a backup returns.
@@ -187,6 +187,16 @@ except the quick actions, if any.
187
187
  rows").
188
188
  - Ownership: **shared** (every signed-in user sees every record) or
189
189
  **per-user** (each user sees only their own).
190
+ - Deleting: how a record goes away, one of
191
+ - **retired by a status**: no delete; a status (Archived, Finished)
192
+ takes it out of the way, and a filter brings it back;
193
+ - **soft-deleted** (the default for a record someone typed): delete
194
+ marks it (`deleted_at`, null means live) and it comes back with
195
+ restore. The view's delete offers Undo, lists leave deleted records
196
+ out, and AI chats (MCP) can delete and restore it;
197
+ - **hard-deleted**: gone for good, back only from a backup. AI chats get
198
+ no delete for it. Say why it must be.
199
+ (`docs/foundation/add-an-entity.md` "Deleting".)
190
200
 
191
201
  ## Open questions
192
202
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tristan2828/ui-foundation",
3
- "version": "4.2.1",
3
+ "version": "4.3.0",
4
4
  "description": "Shared UI foundation for contract-first, database-backed React apps: shadcn primitives, DataTable/EntityForm composites, auth, the gateway error seam, design tokens, lint rules and the AI playbook.",
5
5
  "license": "MIT",
6
6
  "repository": {