← GetDecant

Changelog

Notas de versión de GetDecant. Cada cambio user-facing se publica aquí cuando se mergea la PR correspondiente.

Changelog

All notable changes to GetDecant are documented here. This file is the source of truth for the public getdecant.com/changelog page.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Workflow note: every PR with the changelog label MUST update the [Unreleased] section below before merging. CI enforces this. When a release is cut (gh release create vX.Y.Z), the [Unreleased] block becomes the new version block.

Unreleased

Changed

  • Workflow now requires every PR to follow the GetDecant workflow: PRD-issue first, branch named <type>/<issue#>-<slug>, conventional commits, mandatory Copilot review loop until no unresolved threads, then squash-merge. Documented in CLAUDE.md. (#19, #20)

Fixed

  • SaaS admin impersonation now starts through a server action that sets the tenant cookie as HttpOnly, records an audited impersonation event, and redirects into the tenant dashboard without any document.cookie write in the admin client. (#24)
  • Receipt headers now include the branch address and phone with tenant-level fallback, and the POS ticket preview mirrors the same contact lines when branch data is missing. (#96)
  • Movement audit logs now show actor display names, keep the raw UUID in a tooltip when available, and let operators filter/export by actor without reading raw IDs. (#97)

Added

  • Public /roadmap page (SSR from GitHub Project, filtered by Public=true) with milestone grouping, status sub-buckets, and area / priority / search filters. Cached every 10 minutes; renders an empty/error fallback when the GitHub API or token are unavailable. (#30)
  • 35+ GitHub labels for triage: type/* (8), priority/p0-p3, area/* (15), status/* (6), effort/xs-xl (5), changelog, incident, breaking-change, good-first-issue. (#19, #20)
  • 4 milestones aligned to roadmap buckets: M1 GA Blockers (P0), M2 UX Hardening (P1), M3 Reports + Audit + Compliance (P2), M4 Tech Debt + Polish (P3). (#19, #20)
  • Issue templates: PRD (full spec format), bug (with severity matrix), incident (production outage workflow). (#19, #20)
  • PR template with Copilot loop reminder + changelog gate. (#19, #20)
  • SaaS admin tenant creation now provisions a default Principal branch (MAIN) in the same transaction, and backfills any existing tenants that were still missing a usable default branch. (#22)

0.2.0 — 2026-04-16

Security

  • Critical: UPDATE RLS policy added to branch_transfer_items. Previously the addTransferUnitItemAction server action's "accumulate quantity" branch silently failed because no UPDATE policy existed; adding the same variant twice to a draft transfer kept the original quantity instead of summing. (#18)
  • Critical: /api/identify now requires authentication before invoking the Gemini Vision AI Gateway. Previously unauthenticated requests could trigger billable AI calls. (#18)
  • High (IDOR): /api/sync-errors/resolve now scopes the update to the user's active_tenant_id. Previously any authenticated user could resolve sync errors belonging to other tenants by guessing IDs. (#18)
  • High: receive_branch_transfer RPC now requires explicit branch-level authorization via has_branch_access(to_branch_id). Previously any tenant staff could receive transfers into branches they were not assigned to. (#18)
  • High: receive_branch_transfer RPC validates the bottle is currently located in from_branch_id before reassigning. Previously a bottle moved manually or already transferred could be silently relocated to the destination. (#18)
  • High: /api/prices/competitive returns 403 when looking up products by ID without an active tenant. Previously the admin client (which bypasses RLS) leaked product brand/name across tenants when active_tenant_id was null. (#18)
  • High: has_branch_access() no longer permissively grants access to all branches when a user has zero branch_memberships. Now requires explicit branch membership OR owner/admin role OR saas_admin. Aligns DB-layer authorization with application-layer canAccessAllBranches. (#18)

Fixed

  • Critical bug: receive_branch_transfer column typo (remaining_mlremaining_volume_ml). Bottle transfer movements were recording remaining_volume_ml: 0 in metadata regardless of actual fill level. (#18)
  • Critical bug: getPOSProducts() was aggregating stock across all branches of the tenant. POS at one branch showed inflated stock counts that included other branches' inventory. Now scoped to active branch via PostgREST nested filter + defense-in-depth re-filter in code. (#18)
  • getRecentOrders() throws MissingBranchError when no active branch is set, instead of silently returning cross-branch data. POS is always branch-scoped. (#18)
  • POS home CTA test (Iniciar sesiónEntrar al sistema) updated to match the renamed link from the trial-signup release. (#18)

Added

  • New RPC ship_branch_transfer(p_tenant_id, p_transfer_id, p_shipped_by) reserves source branch stock atomically when a transfer is shipped. Closes the double-spend race where a sale could drain source stock between ship and receive. (#18)
  • New RPC cancel_branch_transfer(p_tenant_id, p_transfer_id, p_cancelled_by) restores reserved source stock when an in_transit transfer is cancelled. (#18)
  • branch_transfers.shipped_by audit column to track who initiated the ship. (#18)
  • PowerSync now syncs the multi-branch tables (branches, branch_memberships, branch_transfers, branch_transfer_items). The new branch_data bucket parameterizes by user-accessible branches so staff offline only receives operational data for branches they can actually access. (#18)

Changed

  • cancelTransferAction and shipTransferAction server actions now call the new RPCs (cancel_branch_transfer, ship_branch_transfer) instead of doing the status flip directly. Stock reservation/restoration is atomic with the status change. (#18)
  • Branch upserts in supabase/seed.sql documented inline — the id = excluded.id is required because the multi-branch migration auto-creates a random-UUID branch for the demo tenant; without updating the PK on conflict, downstream seed inserts fail with FK violations on npx supabase db reset. (#18)

Removed

  • apps/web/app/dashboard/inventory/transferencias/client.tsx — main's old client component was incompatible with the action exports we kept; our flow uses page.tsx with form actions directly. (#18)
  • supabase/.temp/cli-latest removed from version control (path is gitignored; was an old tracked artifact producing noisy diffs on Supabase CLI updates). (#18)
  • .playwright-cli/ — 22 generated Playwright DOM snapshots and console logs untracked. Path is gitignored. (#18)

DB Migrations

  • 20260416120000_fix_branch_transfer_items_update_rls.sql — UPDATE policy for transfer items.
  • 20260416120100_fix_receive_transfer_column_and_auth.sql — fixes column typo + branch-level auth + bottle source-branch validation.
  • 20260416120200_ship_time_stock_reservation.sql — adds ship_branch_transfer, cancel_branch_transfer, redefines receive_branch_transfer, adds shipped_by column.
  • 20260416130000_tighten_has_branch_access.sql — removes permissive default from branch access helper.

Usamos cookies para mejorar tu experiencia y analizar el tráfico del sitio. Política de cookies