Commit graph

1015 commits

Author SHA1 Message Date
Arthur Belleville
3dafba72cc
fix(04-WR-02): set HX-Retarget/HX-Reswap on 422 path in TaskCreateHandler
Without these headers, HTMX used the form's own hx-target="#column-{status}"
+ hx-swap="beforeend", appending the error form into the task column and
destroying all visible task cards. The error form now lands back in the
add-task slot where it belongs.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 10:19:10 +02:00
Arthur Belleville
3d32f2d92f
fix(04-WR-01): check UpdateTask errors in TaskReorderHandler instead of discarding
Both the single-task branch and the main loop were using _, _ = to
discard UpdateTask errors. Now both log the error and return 500 so
the client is never shown a false success when DB writes fail.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 10:18:53 +02:00
Arthur Belleville
392b5321be
fix(04-CR-02): replace fmt.Fprintf in TaskDeleteHandler with TaskCardGone templ component
The raw fmt.Fprintf bypassed templ's auto-escaping pipeline and was
inconsistent with every other handler. Added TaskCardGone(taskID uuid.UUID)
to tasks.templ and updated TaskDeleteHandler to use it. Ran just generate.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 10:18:34 +02:00
Arthur Belleville
e97f4988bd
fix(04-CR-01): add r.ParseForm() to TaskCreateHandler and TaskUpdateHandler
Both handlers were missing the mandatory ParseForm call before reading
PostFormValue. This caused gorilla/csrf (which reads the body for CSRF
token validation) to consume the body, leaving PostFormValue to return
empty strings. TaskReorderHandler was used as the correct reference.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 10:17:49 +02:00
Arthur Belleville
142ca547ea
docs(04): add code review report 2026-05-15 10:10:41 +02:00
Arthur Belleville
879f7b1161
docs(phase-04): complete phase execution — tasks kanban
7/7 TASK requirements verified. Human browser verification done in
plan 04-04 checkpoint (badge count + DnD bugs fixed before approval).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 10:08:02 +02:00
Arthur Belleville
06bbb49a7f
docs(04-04): human checkpoint approved — phase 4 complete
All 7 TASK requirements verified in browser. Two bugs found and fixed
during verification (badge count, drag-and-drop draggable selector).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 10:04:21 +02:00
Arthur Belleville
131c9fd6b3
fix(04): draggable:.task-card-zone — move wrapper not inner card
Sortable.js draggable must match direct children of .sortable-column.
Using .task-card (grandchild) caused Sortable to detach it from its
.task-card-zone wrapper, breaking HTMX OOB swap targets and making
drag appear to do nothing. Changed to .task-card-zone so the full
wrapper moves, keeping id= attributes intact for HTMX round-trips.

Also removed redundant form.dispatchEvent() before htmx.trigger()
which could cause a double submit on reorder.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 10:01:34 +02:00
Arthur Belleville
68f2ccdea3
fix(04): badge count + DnD init — use DOMContentLoaded/htmx:afterSettle
Replace htmx.onLoad (requires htmx at parse time) with native
document.addEventListener('DOMContentLoaded') + 'htmx:afterSettle'
so Sortable.js is guaranteed loaded before init runs.

Add task-count-badge-{status} wrapper IDs and updateBadges() that
recounts .task-card elements on every HTMX settle so badge counts
stay in sync after create, delete, and reorder operations.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 09:56:28 +02:00
Arthur Belleville
8ac0a51969
docs(04-03): complete plan 03 — inline edit + reorder fully implemented
- 04-03-SUMMARY.md created with full execution details
- STATE.md updated: decisions, metrics, notes for plan 03
- ROADMAP.md updated with plan progress (3/4 summaries for phase 4)
2026-05-15 09:40:35 +02:00
Arthur Belleville
f6deb8709b
feat(04-03): remove t.Skip from TestTaskOrderPersists — all 9 TestTask* tests active
- Remove t.Skip("handlers_tasks not yet implemented") from TestTaskOrderPersists
- Full test suite green: go test ./... exits 0, no FAIL lines
- All 9 TestTask* tests active (skip on missing TEST_DATABASE_URL per existing pattern)
2026-05-15 09:38:53 +02:00
Arthur Belleville
5f87d7e0ea
feat(04-03): implement TaskReorderHandler + remove t.Skip from reorder tests
- TaskReorderHandler: POST /tablos/{id}/tasks/reorder updates status+position
- Fetches existing task via GetTaskByID before UpdateTask (T-04-08 mass assignment guard)
- Supports both array form (task_id[]/task_col[]) and single-value form (task_id/status/position)
- Invalid UUIDs silently skipped (D-05); tasks from other tablos skipped (T-04-10)
- Returns updated KanbanBoard outerHTML for HTMX swap
- Remove t.Skip from TestTaskReorderCrossColumn and TestTaskReorderSameColumn
2026-05-15 09:38:28 +02:00
Arthur Belleville
2b299e21f4
feat(04-03): implement TaskEditHandler, TaskUpdateHandler, TaskEditFragment
- TaskEditHandler: GET /tablos/{id}/tasks/{task_id}/edit returns TaskEditFragment pre-filled with existing title+description
- TaskUpdateHandler: POST validates title (required, max 255), updates title+description preserving status+position (T-04-12)
- TaskEditFragment: outer .task-card-zone wrapper with outerHTML round-trip, discard restores via /show
- Sortable.js htmx.onLoad init script added to KanbanBoard (Pitfall 2 protection)
- TaskEditFragment added to tasks.templ; remove t.Skip from TestTaskUpdate
2026-05-15 09:37:46 +02:00
Arthur Belleville
5158eb09af
docs(04-02): complete kanban vertical slice plan — handlers, templates, test activation
- Add 04-02-SUMMARY.md with full decisions and deviation documentation
- Update STATE.md: Plans 01-02 done, add decisions, metrics, notes
- Update ROADMAP.md phase 4 progress (2/4 plans complete)
2026-05-15 09:35:03 +02:00
Arthur Belleville
92ebb5f5fe
feat(04-02): activate task integration tests (RED stubs to GREEN-ready)
- Remove t.Skip from TestTasksKanbanRenders, TestTaskCreate, TestTaskCreateValidation, TestTaskDelete, TestTaskOwnership
- Fix column header strings: 'To do'/'In progress'/'In review' to match TaskColumnLabels
- Add kanban-board id assertion and non-owner 404 check to TestTasksKanbanRenders
- TestTaskUpdate, TestTaskReorder*, TestTaskOrderPersists remain SKIP for Plan 03
2026-05-15 09:33:19 +02:00
Arthur Belleville
889164b437
feat(04-02): KanbanBoard, TaskCard, TaskDeleteConfirmFragment templates
- Add tasks.templ with KanbanBoard, KanbanColumn, TaskCard, TaskCreateFormFragment, TaskDeleteConfirmFragment, AddTaskTrigger, TaskCardOOB
- Add TaskColumns/TaskColumnLabels to tasks_forms.go (moved from web package to break import cycle)
- Update TabloDetailPage signature to accept tasks []sqlc.Task; embed KanbanBoard below tablo header
- Update handlers_tablos.go TabloDetailHandler to fetch tasks via ListTasksByTablo
- Update layout.templ: add sortable.min.js script tag, update footer to Phase 4 · Tasks
2026-05-15 09:32:06 +02:00
Arthur Belleville
181ae79369
feat(04-02): TasksDeps, task handlers, router task routes
- Add handlers_tasks.go: TasksDeps, TaskNewFormHandler, TaskCancelNewHandler, TaskCreateHandler, TaskShowHandler, TaskDeleteConfirmHandler, TaskDeleteHandler, plus stub Edit/Update/Reorder handlers
- Add task routes to router.go (static before parametric per Pitfall 1)
- Add TasksDeps param to NewRouter; update main.go and all test callers
- Move TaskColumns/TaskColumnLabels to templates package to avoid import cycle
2026-05-15 09:31:59 +02:00
Arthur Belleville
2be4cb6bc9
docs(04-01): complete Wave 0 foundation plan summary and state updates
- 04-01-SUMMARY.md: documents migration, sqlc, RED scaffold, Sortable.js, soft-danger CSS
- STATE.md: Phase 4 in-progress, 3 new decisions recorded, metrics row added
- ROADMAP.md: Phase 4 progress updated (1/4 plans)
- REQUIREMENTS.md: TASK-01..07 marked complete
2026-05-15 09:26:31 +02:00
Arthur Belleville
55fb32f1e1
chore(04-01): Sortable.js bootstrap and soft-danger button CSS
- justfile: add sortable_version := "1.15.7" variable
- justfile: bootstrap downloads sortable.min.js from jsDelivr
- justfile: clean removes static/sortable.min.js
- button.css: add .ui-button-soft-danger-md rule with hover and focus-visible states
- static/sortable.min.js: downloaded at 1.15.7 (45 kB)
2026-05-15 09:24:44 +02:00
Arthur Belleville
8b9543db6f
test(04-01): add RED test scaffold and task form structs
- handlers_tasks_test.go: 9 TestTask* functions (TASK-01..07 + IDOR) all skip
- TasksDeps stub struct declared in test file for Plan 02 wiring
- tasks_forms.go: TaskCreateForm, TaskCreateErrors, TaskUpdateForm, TaskUpdateErrors structs
- go build ./... passes; go test -run TestTask exits 0 with all 9 SKIP
2026-05-15 09:24:05 +02:00
Arthur Belleville
c9c826247a
feat(04-01): add tasks migration and sqlc query source
- CREATE TYPE task_status ENUM (todo, in_progress, in_review, done)
- CREATE TABLE tasks with tablo_id FK, position, status columns
- DROP order: table before type in Down migration (Pitfall 3)
- sqlc queries: ListTasksByTablo, InsertTask, GetTaskByID, UpdateTask, DeleteTask, MaxPositionByTabloAndStatus
- migration applied cleanly, sqlc generate produces TaskStatus type and Task struct
2026-05-15 09:22:18 +02:00
Arthur Belleville
2c6c3bf87e
docs(04): create phase plan — 4 plans for Tasks (Kanban)
Wave 1: migration 0004_tasks + sqlc + RED test scaffold + Sortable.js + CSS
Wave 2: board render + task create + delete (TASK-01, TASK-02, TASK-06)
Wave 3: inline edit + drag reorder/move (TASK-03, TASK-04, TASK-05, TASK-07)
Wave 4: human-verify checkpoint

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 09:19:42 +02:00
Arthur Belleville
7f58588f5a
docs(04): create phase 4 tasks-kanban plan (4 plans, 3 waves)
Wave 1 (Plan 01): DB migration, sqlc queries, RED test scaffold, Sortable.js bootstrap, soft-danger CSS.
Wave 2 (Plan 02): Kanban board render + task create + task delete vertical slice (TASK-01, TASK-02, TASK-06).
Wave 3 (Plan 03): Inline task edit + Sortable.js drag reorder/move (TASK-03, TASK-04, TASK-05, TASK-07).
Wave 4 (Plan 04): Human-verify checkpoint — full browser verification of all 7 TASK requirements.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 09:16:17 +02:00
Arthur Belleville
cfd30eb277
docs(04): UI design contract 2026-05-15 09:05:54 +02:00
Arthur Belleville
cdcb335fec
docs(04): UI design contract for Tasks (Kanban) phase
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 09:01:17 +02:00
Arthur Belleville
02cf49ac31
docs(04): add validation strategy 2026-05-15 08:52:20 +02:00
Arthur Belleville
1c7b9d632c
docs(04): research phase tasks-kanban domain 2026-05-15 08:51:06 +02:00
Arthur Belleville
338e7e6e92
docs(state): record phase 4 context session 2026-05-15 08:40:41 +02:00
Arthur Belleville
f31951ce1d
docs(04): capture phase context 2026-05-15 08:40:37 +02:00
Arthur Belleville
58c8231af9
docs(03): mark REVIEW.md status fixed after applying CR/WR fixes
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 08:30:33 +02:00
Arthur Belleville
79435602c4
fix(03): WR-04 add color field error display to create form template
- TabloCreateErrors: add Color field for server-side hex validation error
- TabloCreateFormFragment: render FieldError for color field and update
  placeholder to hex-only hint (#6366f1) matching the validation constraint

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 08:30:27 +02:00
Arthur Belleville
38fe5b3909
fix(03): CR-02 capture user from loadOwnedTablo on update error path
- TabloUpdateHandler: capture user from loadOwnedTablo (was discarded with _)
- Pass captured user to TabloDetailPage on non-HTMX validation error path
  instead of nil, preventing broken layout (no logout button/email shown)
- TabloUpdateHandler: pass tablo.Color to UpdateTablo to preserve color on update (CR-01)
- loadOwnedTablo: pass GetTabloByIDParams{ID, UserID} to DB query (WR-01 call site)
- TabloDeleteHandler: pass DeleteTabloParams{ID, UserID} to DB query (WR-02 call site)
- TabloDeleteHandler: on DB error with HX-Request, render TabloDeleteConfirmFragment
  instead of plain http.Error to avoid broken HTMX DOM state (CR-03)
- renderTabloCreateError: log secondary ListTablosByUser fetch failure (WR-03)
- TablosCreateHandler: validate color with isValidCSSColor (hex only) and surface
  TabloCreateErrors.Color field error to prevent CSS injection (WR-04)
- Add isValidCSSColor helper using ^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$ regex
- Update test call sites for GetTabloByID and DeleteTablo new param types

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 08:30:22 +02:00
Arthur Belleville
fc41883b1f
fix(03): CR-01 WR-01 WR-02 add color to UpdateTablo and user_id filters to GetTabloByID/DeleteTablo
- UpdateTablo SQL: add color = \$4 so color is preserved across title/description edits
- GetTabloByID SQL: add AND user_id = \$2 to push ownership enforcement into the DB layer
- DeleteTablo SQL: add AND user_id = \$2 to push authorization into the DB layer
- sqlc bindings regenerated (UpdateTabloParams+Color, GetTabloByIDParams, DeleteTabloParams)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 08:30:11 +02:00
Arthur Belleville
7b945652d3
docs(03): add code review report 2026-05-15 08:24:09 +02:00
Arthur Belleville
a420a9c45c
docs(phase-03): complete phase execution — TABLO-01..06 verified 2026-05-15 08:21:38 +02:00
Arthur Belleville
450291a697
docs(03-03): complete Phase 3 — advance state and roadmap
Phase 3 Tablos CRUD fully complete: all 3 plans done, TABLO-01..06
closed, 10/10 TABLO tests green, browser verify passed. Advance active
phase to Phase 4 Tasks (Kanban).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 08:10:31 +02:00
Arthur Belleville
b5fa3188f4
docs(03-03): mark Task 3 checkpoint approved — plan 03-03 complete
Human verify passed all 13 sub-checks: ownership 404, CSRF forms on
every mutating form, inline edit/discard, inline delete confirm/cancel,
HX-Redirect navigation, and non-JS 303 fallback. Phase 3 fully complete.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 08:09:24 +02:00
Arthur Belleville
a78221ae1c
docs(03-03): plan 03-03 summary and state 2026-05-15 08:03:58 +02:00
Arthur Belleville
ab6937c1aa
feat(03-03): detail/edit/delete handlers + router wiring; all 10 TABLO tests green
- loadOwnedTablo helper: uuid.Parse, GetTabloByID, ownership check (D-04: 404 not 403)
- TabloDetailHandler: GET /tablos/{id} renders detail page
- TabloEditTitleHandler/ShowTitleHandler: GET /tablos/{id}/edit-title|show-title fragments
- TabloEditDescHandler/ShowDescHandler: GET /tablos/{id}/edit-desc|show-desc fragments
- TabloUpdateHandler: POST /tablos/{id} — validates, updates DB, renders matching zone fragment
- TabloDeleteConfirmHandler/CancelHandler: GET /tablos/{id}/delete-confirm|delete-cancel
- TabloDeleteHandler: POST /tablos/{id}/delete — deletes row, HX-Redirect:/ or 303
- router.go: 9 new routes in RequireAuth group, static-before-parametric order preserved
- Fix [Rule 1 - Bug]: test title "Owner's Tablo" caused HTML entity mismatch — changed to "Owners Detail Tablo"
- go test ./internal/web/... -run TestTablo: 10/10 PASS; full suite: all PASS
2026-05-15 08:02:43 +02:00
Arthur Belleville
6f167e2956
feat(03-03): detail page, edit and delete templ fragments + TabloUpdateErrors
- TabloDetailPage: full detail layout with title/desc/delete zones
- TabloTitleDisplay/EditFragment: outerHTML-swappable title zone with _zone=title hidden field
- TabloDescDisplay/EditFragment: outerHTML-swappable desc zone with _zone=desc hidden field
- TabloDeleteButtonFragment: canonical single-source delete zone (TabloCard now delegates here)
- TabloDeleteConfirmFragment: inline confirm with "Delete tablo?", "Yes, delete", "Keep tablo"
- TabloNotFoundPage: 404 page with UI-SPEC copy
- TabloUpdateErrors struct added to tablos_forms.go
- just generate + go build ./... both exit 0
2026-05-15 07:59:10 +02:00
Arthur Belleville
878ab69602
docs(03-02): complete plan 02 — checkpoint approved, SUMMARY + STATE finalized
- Task 3 human-verify checkpoint approved: dashboard, HTMX create, validation, non-JS fallback all confirmed
- SUMMARY updated: all 3 tasks complete, checkpoint outcome documented
- STATE updated: plan 02 marked complete, commit hashes recorded
- index.templ deletion fix noted as final deviation

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 07:56:44 +02:00
Arthur Belleville
c08da7f5bd
fix(03-02): delete retired index.templ to stop templ generating stale imports 2026-05-15 07:51:50 +02:00
Arthur Belleville
c4406cf16c
docs(03-02): plan 02 SUMMARY + STATE update — checkpoint at Task 3
- 03-02-SUMMARY.md: TablosDeps, handler contracts, template contracts,
  4/10 tests green, 6 RED for Plan 03, known stubs documented
- STATE.md: 2 new decisions, plan 02 metrics row added, notes updated
- ROADMAP.md: phase 3 progress updated (2/3 summaries)
2026-05-15 00:22:16 +02:00
Arthur Belleville
5db9215a73
feat(03-02): tablo handlers + router wiring — list/new/create green
- Implement TablosListHandler, TablosNewHandler, TablosCreateHandler in
  handlers_tablos.go replacing the Plan 01 stub
- TablosCreateHandler: reads via r.PostFormValue, validates title (required,
  <=255), inserts with pgtype.Text nullable params, sends HX-Retarget +
  HX-Reswap on HTMX success, 303 redirect on non-HTMX success
- router.go: replace r.Get("/", IndexHandler()) with TablosListHandler;
  add GET /tablos/new and POST /tablos (static before parametric — Pitfall 1)
- handlers.go: remove IndexHandler + unused auth/csrf imports
- index.templ: reduced to bare package declaration (dashboard moved to tablos.templ)
- index_templ.go: deleted (empty templ file generates broken import)
- TestTabloList, TestTabloList_Empty, TestTabloCreate, TestTabloCreate_Validation: PASS
- TestSignup, TestLogin, TestLogout, TestCSRF: still PASS (no regression)
2026-05-15 00:20:25 +02:00
Arthur Belleville
43ddf25364
feat(03-02): tablos templates — dashboard, empty state, card, create form, OOB-clear
- Create backend/templates/tablos.templ with TablosDashboard, TablosEmptyState,
  TabloCard, TabloCreateFormFragment, TabloCardWithOOBFormClear components
- Create backend/templates/tablos_forms.go declaring TabloCreateForm and
  TabloCreateErrors types (mirrors auth_forms.go pattern)
- Update layout.templ footer: "Phase 2 · Authentication" → "Phase 3 · Tablos"
- TabloCardWithOOBFormClear emits OOB div as top-level sibling (Pitfall 5)
- TabloCard guards description/color rendering with pgtype.Text null checks
- All UI-SPEC copywriting copy strings present; templ generate succeeds
2026-05-15 00:17:56 +02:00
Arthur Belleville
2f22d68776
docs(03-01): complete Plan 01 — migration, test scaffold, button CSS
- 03-01-SUMMARY.md: tablos schema foundation, RED test scaffold, button CSS variants
- STATE.md: decisions + metrics for 03-01; phase 3 status updated
- ROADMAP.md: phase 3 plan progress (1/3 complete)
- REQUIREMENTS.md: TABLO-01..06 marked complete
2026-05-15 00:15:36 +02:00
Arthur Belleville
2c1b186fb7
feat(03-01): add ui-button-solid-danger-md and ui-button-soft-neutral-md CSS variants
- Danger variant: #b91c1c bg, #991b1b hover, min-height 44px (WCAG 2.5.5)
- Neutral-soft variant: #f1f5f9 bg, #e2e8f0 hover, #334155 text, min-height 44px
- All pseudo-class selectors top-level (no CSS nesting per Phase 1 convention)
- static/tailwind.css updated via just generate (Pitfall 4: imported CSS passes through)
2026-05-15 00:13:56 +02:00
Arthur Belleville
c8f44b1ad2
test(03-01): add TablosDeps stub and RED integration test scaffold for TABLO-01..06
- handlers_tablos.go: TablosDeps stub type enabling test compilation
- handlers_tablos_test.go: 10 integration tests (RED baseline) for all TABLO-01..06 paths
  - TestTabloList, TestTabloList_Empty, TestTabloCreate, TestTabloCreate_Validation
  - TestTabloDetail_Owner, TestTabloDetail_NonOwner, TestTabloDetail_InvalidID
  - TestTabloUpdate, TestTabloDeleteConfirm, TestTabloDelete
- router.go: NewRouter accepts TablosDeps as second deps parameter
- handlers_auth_test.go, handlers_test.go, csrf_test.go: update NewRouter call sites
- cmd/web/main.go: construct and pass TablosDeps to NewRouter
2026-05-15 00:13:31 +02:00
Arthur Belleville
f1b8d6e629
feat(03-01): add tablos migration and sqlc queries
- 0003_tablos.sql: tablos table with user_id FK + ON DELETE CASCADE + tablos_user_id_idx
- tablos.sql: 5 named queries (ListTablosByUser, GetTabloByID, InsertTablo, UpdateTablo, DeleteTablo)
- UpdateTablo sets updated_at = now() explicitly (Pitfall 7)
- color not editable in UpdateTablo per Phase 3 scope
- sqlc generates Tablo struct with pgtype.Text for description/color (not committed per .gitignore convention)
2026-05-15 00:10:40 +02:00
Arthur Belleville
f53b54637b
docs(03): plan phase 3 — Tablos CRUD (3 plans, 3 waves)
Plans cover TABLO-01..06 via MVP vertical slices: foundation (migration
+ sqlc + test scaffold + button CSS), list+create (dashboard, inline
form, OOB swap), and detail+edit+delete (ownership 404, inline edit
fragments, inline confirm delete). Includes Nyquist VALIDATION.md and
PATTERNS.md with real analog excerpts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 00:08:08 +02:00