Skip to content
Back to Launch documentation

Download MarkdownOriginal source on GitHub

Launch package product mapping concurrent fix

Fixed AUTH-03 in authorization reviews. Only modified the Launch server and corresponding regression tests; SDK was not deployed or released; authorization boundaries for Licentivo and SDK remain unchanged.

Changes

  • When saving a mapping, lock the shared Launch product record first within the transaction, then lock the package version. Save requests from different packages or processes follow the same product lock; conflicting requests return HTTP 409 PRODUCT_MAPPING_CONFLICT.
  • products.licentivo_product_id stores stable public product routes. After the first successful mapping save, other packages of the same Launch product can only choose this Licentivo product; selecting different strategies is allowed. This field does not store feature permissions, device quotas, or customer authorization status.
  • Customer identity reads stable routes, no longer selecting products based on the highest version across all packages. The same bindings are checked when publishing packages and generating SDK access configurations.
  • Old database automatically adds nullable fields. For data without stable fields, refer sequentially to purchase history with payment, historical release records, and remaining mappings; if multiple products exist at the same priority, conflict is clearly indicated, no guessing. The only purchased product takes precedence over unrelated drafts, then saving compatible mappings can solidify bindings. Product content editing retains bindings.

Historically wrong data sold to multiple Licentivo products still requires manual verification; this time purchase records or remote licenses will not be overwritten. When switching to another Licentivo product, a new Launch product should be created; the original product route cannot be rewritten using a new package.

Implementation: see Mapping Save , Product Route , Identity Issuance , Release Validation , Access Check , Data Model .

Local verification

Checks Results
Pre-fix implementation comparison The same regression test consistently caught two conflicting saves simultaneously as expected to fail.
Regression of the fixed mapping project. One conflicting request succeeds and the other returns 409; both compatible saves succeed; identity is unaffected by erroneous drafts after payment sync; SDK integration layer accepts correct product context.
Historical data protection. Priority for purchased routes, ambiguous error reporting, erroneous drafts prevented from publishing, SDK configuration cannot be generated from erroneous historical releases, and content editing retains bindings—all passed.
Go full source code package and MySQL regression. 192 test records passed, including subcases; no failures. TestProductUploadRoundTrip skipped, not counted as passed.
Old database structure upgrade. Structures missing route columns are filled with nullable fields after initialization; repeated initialization passes.
Real Launch and Licentivo integrated with Go SDK. 13 business stages passed, covering purchases, real signature execution, normal closure recovery, exit, remote unbinding, old generation, renewals and refunds, account cancellation, and rejection/decline operations.
Final additional testing. Passed mapping regression in a new empty database, including checks for historical release access configuration; go vet passed.

After completing full regression and real service integration, a final consistency check for SDK integration was added, with a separate re-run of regression and go vet including this scenario. Expected failures in the old implementation demonstrate that the test can catch original race conditions, not unresolved regression failures.

For joint debugging, we use a local standalone MySQL 8.0.32, the current Licentivo service, and the actual Go SDK; payment channels and DeepL use isolated mock services, so no actual charges or paid translations occur. Special tests for concurrency and historical error mapping use the real Launch business, MySQL, and protocol simulator; we do not claim that all nine SDKs completed this round of real service integration.

192.168.2.177 was not accessed in this round. The temporary MySQL and Licentivo processes started this time have been stopped, and the original services remain. The original materials are in the ignored directory .local/mapping-fix-20261024/. A summary for sharing can be found in Verification Evidence .