Build image / build-and-push (push) Successful in 17s
Critical: - useAddShare/useUpdateShareRole no longer parse the response with the list's Share schema — the backend returns a bare GardenShare (no email/displayName), so every successful invite/role-change was throwing and showing a false error. onSuccess refetches the list, which has the full data. - ShareGardenModal surfaces role-change / remove failures (mutate onError → the dialog's Alert) instead of swallowing them; Modal busy now covers all three pending states. Robustness / defense in depth: - Inspector/PlopInspector patch() early-returns when readOnly, so a blur can't fire a mutation if the role was downgraded mid-edit. - onPickPlant guards canEdit. - Ownership is now the authoritative ownerId==me check (GardenCard via a currentUserId prop, GardenEditorPage via useMe), so a missing my_role can never lock an owner out or show them a Leave button. Cleanup: - Shared cardActionClass/cardDangerClass (GardenCard + PlantCard). - Normalized the read-only <fieldset> indentation; dropped the dead useShares `enabled` param. tsc --noEmit clean; 24/24 vitest; production build green. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01JdQpdYYsTgtkJBxbcpAszi