Skip to content

Context-items UI: project + story panels + picker#116

Merged
datashaman merged 4 commits into
mainfrom
feature/context-assets-ui
May 10, 2026
Merged

Context-items UI: project + story panels + picker#116
datashaman merged 4 commits into
mainfrom
feature/context-assets-ui

Conversation

@datashaman
Copy link
Copy Markdown
Owner

Summary

Slice 8 of the project/story context-asset stack — the user-facing surface for assets that the prior slices wired up under the hood.

Three Volt-style single-file Livewire pages under resources/views/pages/context-items/:

  • project-assets-panel — list, create (text/link/file), edit, delete project-scoped ContextItems. File uploads go through AssetUploader (first WithFileUploads usage in the repo).
  • story-assets-panel — same shape, story-scoped, with a reopen-approval banner. Mutations bump the Story revision via StoryRevisionLifecycle::recordContentArtifactChanged.
  • story-context-picker — checkbox list over Story::availableContextItems(). Story-scoped items render pre-checked and disabled. Save calls ContextItemSelector::bulkSet() once per save (single approval-reopen). Tampered-in story-scoped IDs are silently filtered before reaching the selector.

Permissions are inline on every mount and mutation: in_array($projectId, $user->accessibleProjectIds(), true) — anyone in the project's team can manage assets, matching the read-access bar.

Embedded:

  • pages/projects/⚡show.blade.php — new "Assets" section after features
  • pages/stories/⚡show.blade.php — new "AI Context" section (picker + story panel) above the plan area

Test plan

  • 19 new Livewire tests cover: list scoping, mount-as-non-member 403, create per type, file upload happy path, edit, delete, picker prefill, bulkSet diff (single reopen), no-op save (no reopen), tampered-ID filter.
  • Existing project + story show tests (48 tests) still pass with the new embeds.
  • All 73 ContextItem tests pass.
  • Reviewer: load a project + story in the browser, exercise create/edit/delete/upload/picker; confirm reopen warning is visible.

🤖 Generated with Claude Code

datashaman and others added 2 commits May 10, 2026 11:16
Three Volt-style single-file pages under
`resources/views/pages/context-items/`:

- `project-assets-panel` — list/create/edit/delete project-scoped
  ContextItems. Supports text, link, and file types. File uploads
  go through `AssetUploader` (first `WithFileUploads` usage in the
  repo). Edits route through `ContextItemWriter` so file metadata
  stays immutable.
- `story-assets-panel` — same shape but story-scoped, with a
  reopen-approval banner. Mutations bump the Story revision via
  `StoryRevisionLifecycle::recordContentArtifactChanged`.
- `story-context-picker` — checkbox list over
  `Story::availableContextItems()`. Story-scoped items render
  pre-checked and disabled. Save calls
  `ContextItemSelector::bulkSet()` once for a single
  approval-reopen per save. Tampered-in story-scoped IDs are
  silently filtered before reaching the selector.

Permissions are inline: every mount and mutation gates on
`in_array($projectId, $user->accessibleProjectIds(), true)`,
matching the `pages/projects/⚡show.blade.php` pattern.

Embedded the project panel into the project show page (Assets
section) and the picker + story panel into the story show page
(AI Context section, above the plan area).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tests don't run `npm run build`, so `public/build/manifest.json`
doesn't exist. Any view that pulls in `partials/head.blade.php`
(every authenticated page, every auth screen) was 500ing with
`ViteManifestNotFoundException`. That masked 16 pre-existing test
failures unrelated to functionality.

Call `withoutVite()` in the base TestCase setUp — Laravel's built-in
helper swaps the container binding for a stub that returns empty asset
markup. The whole suite is now green (568 tests, 0 failures).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the test harness and adds new Livewire feature tests for the Context Items UI (project assets panel, story assets panel, and story context picker), aiming to make view-based tests independent from a built Vite frontend and to validate core user flows/permissions.

Changes:

  • Added a global withoutVite() call in tests/TestCase.php to prevent ViteManifestNotFoundException during view rendering in tests.
  • Added Livewire tests for story context picker behavior (listing/prefill/save/no-op/tamper filtering/403 for non-members).
  • Added Livewire tests for project and story assets panels (scoping, CRUD basics, upload happy path for project panel, and 403 for non-members).

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

File Description
tests/TestCase.php Disables Vite in test setup so view assertions don’t depend on a built manifest.
tests/Feature/ContextItem/Livewire/StoryContextPickerTest.php Adds coverage for picker list/prefill/save behaviors and authorization.
tests/Feature/ContextItem/Livewire/StoryAssetsPanelTest.php Adds coverage for story-owned asset panel scoping + text create/edit/delete effects.
tests/Feature/ContextItem/Livewire/ProjectAssetsPanelTest.php Adds coverage for project asset panel scoping, CRUD, and file upload happy path.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/Feature/ContextItem/Livewire/ProjectAssetsPanelTest.php Outdated
Comment thread tests/Feature/ContextItem/Livewire/ProjectAssetsPanelTest.php Outdated
Comment thread tests/Feature/ContextItem/Livewire/StoryAssetsPanelTest.php
datashaman and others added 2 commits May 10, 2026 11:50
- Rename misleading `$story` (it was a Feature) to `$feature` in the
  panel rendering test.
- Replace the "non-member cannot mutate" test that only asserted mount
  status with one that walks every mutation entry point and pins that
  the row stays untouched. The mount gate is what fires; the test now
  documents and verifies that.
- Story panel: add link create + file upload coverage. The file test
  also pins current behaviour — `AssetUploader` does not call the
  approval-reopen helper or attach to the pivot for story-scoped file
  uploads, so neither the revision nor the selection moves. Future
  work to align this with text/link create paths now has a failing
  test to flip.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- AssetUploader: story-scoped file uploads now reopen story approval and
  auto-attach to the context_item_story pivot, matching the text/link path
  (StoryRevisionLifecycle + DB::transaction added)
- Project + story panels: catch InvalidArgumentException from AssetUploader
  and ContextItemWriter; surface as a validation error instead of 500ing
- Panels: show URL for link items and original_name for file items in the
  item list (previously only showed bare title)
- StoryAssetsPanelTest: flip file upload test from pinning the old broken
  behaviour to asserting the correct contract

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@datashaman datashaman merged commit 0323e5f into main May 10, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants