Skip to content

Polecat: consume JasperFx rc.2 / Weasel alpha.8 dedupe + lift wave (#125–#138), cut 4.0.0-rc.1#139

Merged
jeremydmiller merged 12 commits into
mainfrom
feature/consume-jfx-weasel-rc2
May 20, 2026
Merged

Polecat: consume JasperFx rc.2 / Weasel alpha.8 dedupe + lift wave (#125–#138), cut 4.0.0-rc.1#139
jeremydmiller merged 12 commits into
mainfrom
feature/consume-jfx-weasel-rc2

Conversation

@jeremydmiller
Copy link
Copy Markdown
Member

Consumes the Critter Stack 2026 dedupe/lift wave: types Polecat used to declare locally were lifted into JasperFx 2.0.0-rc.2 / JasperFx.Events and Weasel.Core/SqlServer 9.0.0-alpha.8, which this branch re-pins to. Each issue is one commit; type-forwards use global-using aliases (one GlobalUsings.cs per assembly) so unqualified references keep resolving to the canonical lifted types.

Per-issue commits

Commit Issue Summary
72f05ac #127 #128 #135 foundation re-pin rc.2/α8; type-forward DeleteStyle + TenancyStyle, DcbConcurrencyException + ProgressionProgressOutOfOrderException, IdentityAttribute + FindIdMember
9acda3e #125 adopt shared IProjectionCoordinator + JasperFx.StorageConstants
3e08f0a #126 reduce ProjectionCoordinator to a ProjectionCoordinatorBase subclass
f7c4b5c #129 adopt lifted ResilientEventLoader + SkippedEventsCountObserver
9df48e9 #130 type-forward Metadata markers (ISoftDeleted/IVersioned/ITracked) to JasperFx.Metadata
5e73547 #131 implement lifted IPatchExpression<T> superset + RemoveAction
838af8b #132 consume OpenTelemetryOptions base + type-forward TrackLevel
a00c774 #133 implement IDocumentSchemaResolver from JasperFx.Events
0866839 #134 consume IInitialData<TStore> + IConfigureStore<TOptions> generics
d86db84 #137 adopt Weasel.Core α8 dedupe types — HiloSequenceBase + serialization enums
325d3ea #136 #138 ILongVersioned (long) document revisions + bigint version column
747e00a cut 4.0.0-rc.1

Foundation bump

Pins move to JasperFx* 2.0.0-rc.2 and Weasel* 9.0.0-alpha.8. Polecat itself graduates to its first release candidate, 4.0.0-rc.1 (main had independently moved to 4.0.0-alpha.10; rc.1 supersedes it).

⚠️ Reviewer attention: bigint version-column widening (#136/#138)

Decision D2 makes the document version column bigint always (carrying IRevisioned int — downcast on read — and ILongVersioned long). Existing tables with an int version column are widened in place by DocumentTableEnsurer.WidenVersionColumnIfNeededAsync:

  • It drops any lingering version default constraint, then runs ALTER COLUMN ... bigintnever a drop/recreate, so rows are preserved. (SQL Server rejects ALTER COLUMN while a default references the column, and Weasel emits only a bare ALTER COLUMN, so the default handling lives here.) It is idempotent.
  • The version column now has no default — every write sets it explicitly, the default was dead weight, and removing it eliminates default-constraint migration churn.
  • Covered by version_column_widening_migration (proves int→bigint preserves data) and long_versioned_operations (a Version > Int32.MaxValue round-trip + concurrency).

Validation

  • All projects build clean (Debug): Polecat, Polecat.Tests, Polecat.AspNetCore, Polecat.EntityFrameworkCore(.Tests), Polecat.AotSmoke — no new warnings.
  • Polecat.Tests full suite (net10.0): 1144 pass / 3 pre-existing skip / 0 fail.
  • Polecat.EntityFrameworkCore.Tests (net10.0): 37 pass / 0 fail (including a forced widening path).

Closes #125 #126 #127 #128 #129 #130 #131 #132 #133 #134 #135 #136 #137 #138

🤖 Generated with Claude Code

jeremydmiller and others added 12 commits May 20, 2026 10:57
…ncyStyle (#127), DcbConcurrencyException+ProgressionProgressOutOfOrderException (#128), IdentityAttribute+FindIdMember (#135)

Foundation re-pin from the alpha line to the JasperFx 2.0 rc:
  JasperFx                        2.0.0-alpha.20 -> 2.0.0-rc.2
  JasperFx.Events                 2.0.0-alpha.20 -> 2.0.0-rc.2
  JasperFx.RuntimeCompiler        5.0.0-alpha.8  -> 5.0.0-rc.2
  JasperFx.SourceGeneration       2.0.0-alpha.9  -> 2.0.0-rc.2
  JasperFx.Events.SourceGenerator 2.0.0-alpha.12 -> 2.0.0-rc.2
  Weasel.SqlServer                9.0.0-alpha.7  -> 9.0.0-alpha.8
  Weasel.EntityFrameworkCore      9.0.0-alpha.7  -> 9.0.0-alpha.8

The rc lifted three families of types Polecat declared locally, so the bump
does not compile until all three collisions are resolved — bundled here as
one green checkpoint (the rest of the consume/dedupe issues land one per
commit on this branch).

#127 (jasperfx#327) — TenancyStyle + DeleteStyle:
  - Deleted Polecat.Metadata.DeleteStyle and the inline StoreOptions
    TenancyStyle enum (both ordinal-identical to the lifted enums:
    Remove=0/SoftDelete=1, Single=0/Conjoined=1).
  - Added src/Polecat/GlobalUsings.cs aliasing TenancyStyle ->
    JasperFx.MultiTenancy.TenancyStyle and DeleteStyle -> JasperFx.DeleteStyle,
    mirroring Marten's GlobalUsings.cs. Fixed two fully-qualified
    Metadata.DeleteStyle refs in QuerySession.

#128 (jasperfx#328) — DcbConcurrencyException + ProgressionProgressOutOfOrderException:
  - Deleted Polecat.Events.Dcb.DcbConcurrencyException (byte-identical to the
    lifted JasperFx.Events type) and Polecat.Exceptions.ProgressionProgressOutOfOrderException
    (the lifted JasperFx.Events.Daemon type folds in Polecat's richer 3-arg
    ctor + ProjectionName/ExpectedFloor/AttemptedCeiling props verbatim).
  - Global aliases for both; dropped the now-dead using in UpdateProjectionProgress.
    The inline catch(2627) insert-conflict mapping is untouched.

#135 (jasperfx#335) — IdentityAttribute + ID resolution:
  - Deleted Polecat.Attributes.IdentityAttribute; aliased IdentityAttribute ->
    JasperFx.IdentityAttribute (so [Identity] keeps resolving). Rewrote the test
    that used the fully-qualified [Polecat.Attributes.Identity] to [JasperFx.Identity].
  - DocumentMapping.FindIdProperty now delegates to the side-effect-free
    JasperFx.DocumentIdentity.FindIdMember(type, predicate), passing Polecat's
    own valid-id-type predicate (SupportedIdTypes + TryResolveValueTypeId, both
    nullable-aware) so strong-typed-id "Id" members are still recognized — the
    shared helper's default ValidIdTypes set is scalar-only. Result filtered to
    PropertyInfo to preserve Polecat's property-only contract (both call sites
    need PropertyInfo for .PropertyType / .SetValue).

Test-assembly GlobalUsings.cs added to Polecat.Tests, Polecat.EntityFrameworkCore,
and Polecat.EntityFrameworkCore.Tests for the lifted names those assemblies
reference unqualified (global usings don't cross assembly boundaries).

Validated:
  Polecat.Tests (net10.0):                    1133 pass / 3 pre-existing skips / 0 fail
  Polecat.EntityFrameworkCore.Tests (net10.0):  37 pass / 0 fail
  Polecat.AotSmoke (net10.0):                 builds + runs clean
  All projects build clean under -c Debug/Release

Closes #127, #128, #135.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…eConstants

Two "adopt the already-shared thing" cleanups from the Critter Stack 2026
dedupe pillar (jasperfx#214), both Polecat-side only (no upstream work).

1. IProjectionCoordinator — stop re-declaring it
   - Polecat.Events.Daemon.Coordination.IProjectionCoordinator now inherits
     the member-for-member-identical JasperFx.Events.Daemon.IProjectionCoordinator
     (lifted from Marten); the five duplicated members are deleted. Mirrors
     Marten's empty inheriting interface.
   - The generic marker IProjectionCoordinator<T> inherits the lifted
     IProjectionCoordinator<T> and relaxes its constraint from
     `where T : IDocumentStore` to the shared `where T : class`. The concrete
     ProjectionCoordinator<T> gains `class` (now `where T : class, IDocumentStore`)
     so it still satisfies the relaxed interface; the DI registration in
     PolecatConfigurationExpression already used `class, IDocumentStore`.

2. JasperFx.StorageConstants
   - Deleted Polecat.Tenancy (its only member was DefaultTenantId = "*DEFAULT*",
     byte-identical to JasperFx.StorageConstants.DefaultTenantId). All consumers
     (~19 refs across sessions, bulk insert, event-store explorer, projection
     replay, table DDL, ITenancy impls, + 4 test files) now reference
     JasperFx.StorageConstants.DefaultTenantId. Removes the silent-drift hazard
     if the sentinel ever changes upstream.
   - The "tenant_id" string literal in the 6 schema/table builders (DocumentTable,
     DocumentIndex, EventsTable, StreamsTable, NaturalKeyTable, EventTagTable)
     now uses JasperFx.StorageConstants.TenantIdColumn. Operations/LINQ column
     references keep the literal (out of the issue's "table classes" scope; same
     resolved value, lower drift risk).

Validated:
  All projects build clean (Debug)
  Polecat.Tests Daemon+Schema+MultiTenancy+Documents (net10.0): 152 pass / 3 skip / 0 fail
  (schema tests confirm the tenant_id constant emits identical DDL)

Closes #125.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…class (consume jasperfx#326)

jasperfx#326 (PR jasperfx#336) lifted the projection-coordinator execute loop
into JasperFx.Events.Daemon.ProjectionCoordinatorBase. Polecat's ExecuteAsync
was a slot-for-slot mirror of Marten's, so this is the Polecat-side consumption.

Polecat.Events.Daemon.Coordination.ProjectionCoordinator now subclasses
ProjectionCoordinatorBase (and still declares Polecat's empty IProjectionCoordinator
sub-interface, mirroring Marten):

  - Base ctor supplied with: BuildDistributor(store, loggerFactory) [now static so
    it can run in the base-ctor argument list], the StoreOptions.ResiliencePipeline,
    TimeProvider.System, and the three settings converted to TimeSpan
    (LeadershipPollingTime is int-ms -> TimeSpan.FromMilliseconds; AgentPauseTime
    and HealthCheckPollingTime are already TimeSpans on DaemonSettings).
  - Abstract seams implemented: ResolveDaemon(set) -> DaemonFor((PolecatDatabase)set.Database)
    keeping the per-database dictionary cache in the subclass; ResolvedDaemons()
    snapshots that cache; the three tenancy-aware daemon accessors
    (DaemonForMainDatabase / DaemonForDatabase / AllDaemonsAsync) are overrides.
  - Deleted the lifted-into-base members: ExecuteAsync, the two agent helpers
    (StartAgentsIfNecessaryAsync / StopAgentsIfNecessaryAsync), StopAllAgentsAsync,
    and the bespoke StartAsync/StopAsync/PauseAsync/ResumeAsync lifecycle with its
    _paused / _runCts / _runTask tracking. The lazy Distributor property is gone —
    the base exposes Distributor (set once in the ctor).

Behavioral change (the #326 fix): the shared loop wraps StartAgentAsync in the
ResiliencePipeline and, on failure, ejects the paused shard and releases the
set's lock so another node can pick it up. Polecat previously started agents raw
with no lock-release-on-failure — this closes that gap. Pause/Resume/Stop
bookkeeping is normalized on the base's single cancellation-source + awaited
runner model.

Validated:
  All projects build clean (Debug)
  Polecat.Tests.Daemon (net10.0): 53 pass / 3 pre-existing skips / 0 fail
  (covers async_daemon_tests + multi_tenant_daemon_tests hot-cold handover on SQL Server)

Closes #126.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…(consume jasperfx#329)

jasperfx#329 (PR jasperfx#340) lifted SkippedEventsCountObserver,
ResilientEventLoader, and EventLoaderException into JasperFx.Events.Daemon.

- Deleted Polecat.Events.Daemon.SkippedEventsCountAugmenter; PolecatDatabase
  now subscribes the lifted SkippedEventsCountObserver. The lifted observer
  adds a `ShardName == HighWaterMark` guard (strict superset) — harmless here
  since Polecat only subscribes it for the HWM tracker.
- Wrapped PolecatEventLoader with the lifted
  ResilientEventLoader(Options.ResiliencePipeline, inner, database) at the
  IEventStore.BuildEventLoader site (database is already the IEventDatabase the
  decorator wants). Dropped the inline _resilience.ExecuteAsync(...) Polly call
  from PolecatEventLoader.LoadAsync — the loader is now the bare inner loader;
  resilience is layered by the decorator. Removed the now-unused _resilience
  field + `using Polly;`.
- Bonus parity: Polecat now reports loading metrics via
  EventRequest.Metrics.TrackLoading() (provided by the decorator) — it did no
  loading metrics before.

Validated:
  All projects build clean (Debug)
  Polecat.Tests.Daemon (net10.0): 53 pass / 3 pre-existing skips / 0 fail
  (covers event_loader_tests, event_loader_resiliency_tests, and the
  skipped-events-count tracker behavior)

Closes #129.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…perfx#330)

jasperfx#330 (PR jasperfx#342) lifted ISoftDeleted, IVersioned, ITracked to
JasperFx.Metadata.

- Deleted Polecat.Metadata.{ISoftDeleted,IVersioned,ITracked}; aliased all
  three to the JasperFx.Metadata types in src/Polecat + test-assembly
  GlobalUsings.cs (the names are referenced unqualified throughout). ISoftDeleted
  and IVersioned (Guid Version) are byte-identical straight rebinds. Fixed one
  short-qualified `Metadata.ITracked` pattern-match in DocumentSessionBase.SyncMetadata.
- ITracked was lifted with non-nullable string members (Marten's shape) vs
  Polecat's string?. Per the issue, adjusted the concrete classes rather than the
  interface: the TrackedDoc / FullMetadataDoc test documents now declare
  non-nullable `string ... = string.Empty` for CorrelationId/CausationId/
  LastModifiedBy (SyncMetadata always copies non-null session values onto them;
  no test asserts a null default). This clears the CS8766 return-nullability
  warnings the rebind surfaced.

IRevisioned is intentionally NOT included (tracked in jasperfx#341 pending the
int/long revision unification — see #136/#138).

Validated:
  All projects build clean (Debug); no new nullability warnings (the 3 remaining
  CS8767 on TenantId/IHasTenantId are pre-existing, unrelated to #130)
  Polecat.Tests Metadata+SoftDeletes+Concurrency+Versioning (net10.0): 59 pass / 0 fail

Closes #130.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…onsume jasperfx#331)

jasperfx#331 (PR jasperfx#343) lifted IPatchExpression<T> as Marten's superset
+ RemoveAction into JasperFx.Events. Polecat's interface was a subset, so
adoption grows the implementation.

- Deleted Polecat.Patching.IPatchExpression<T> + RemoveAction. RemoveAction
  (ordinals identical: RemoveFirst=0/RemoveAll=1) is aliased in src + test
  GlobalUsings.cs. IPatchExpression<T> is an open generic (can't be a using
  alias), so the two files that name it unqualified — PatchExpression.cs and
  PatchingExtensions.cs — gain `using JasperFx.Events;`.
- Grew PatchExpression<T> to the full lifted interface:
  * Rename(string, Expression<Func<T, object>>) — replaces Polecat's generic
    Rename<TElement>. ToPath already unwraps the Func<T,object> boxing Convert;
    a small UnwrapMemberType helper recovers the real member type to keep the
    scalar/complex JSON_MODIFY distinction. (No test exercised the old generic
    Rename, so it's dropped rather than kept as a convenience method.)
  * AppendIfNotExists / InsertIfNotExists / Remove predicate overloads —
    these require translating an Expression<Func<TElement,bool>> into a JSON
    array search, which Polecat's JSON_MODIFY patch translation doesn't do yet.
    Per the issue, they throw NotSupportedException with a clear message
    pointing at the supported non-predicate overload, so the interface members
    exist without silently misbehaving.

Validated:
  All projects build clean (Debug)
  Polecat.Tests.Patching (net10.0): 43 pass / 0 fail
  (the 42 existing patch ops via Set/Append/Insert/Remove/Delete/Increment/
   Duplicate + non-predicate IfNotExists are unchanged; new predicate overloads
   are NotSupported and not exercised)

Closes #131.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…Level (consume jasperfx#332)

jasperfx#332 (PR jasperfx#344) lifted the common OpenTelemetryOptions base +
TrackLevel to JasperFx.OpenTelemetry.

- Polecat.Internal.OpenTelemetry.OpenTelemetryOptions had nothing beyond the
  base (TrackConnections + a "Polecat"-named Meter), so it's now a thin subclass
  of JasperFx.OpenTelemetry.OpenTelemetryOptions with `: base("Polecat")`. Kept
  as a subclass (option 2 in the issue) rather than consuming the base directly
  so the public name + parameterless construction survive — StoreOptions does
  `OpenTelemetry { get; } = new()` and a test does `new OpenTelemetryOptions()`.
- Deleted Polecat's TrackLevel enum (ordinals identical: None=0/Normal=1/
  Verbose=2); aliased TrackLevel -> JasperFx.OpenTelemetry.TrackLevel in src +
  test GlobalUsings.cs. TrackConnections + Meter now come from the base.
- PolecatTracing ActivitySource holder intentionally left as-is (per the issue
  and the upstream pass-N audit — per-library OTel sources are wanted).

Validated:
  All projects build clean (Debug)
  Polecat.Tests OpenTelemetry + document_store_usage (net10.0): 13 pass / 0 fail
  (covers Normal/Verbose/None track-level tracing + the flattened
   OpenTelemetryTrackConnections store-usage description)

Closes #132.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
… jasperfx#333)

jasperfx#333 (PR jasperfx#345) lifted IDocumentSchemaResolver to JasperFx.Events
preemptively — Polecat had no equivalent. This implements it as the cross-store
"where does this document live" surface.

- New Internal.PolecatDocumentSchemaResolver : IDocumentSchemaResolver maps
  Polecat's SQL Server conventions: documents -> pc_doc_{typename}, event store ->
  pc_events / pc_streams / pc_event_progression, all under the single
  DatabaseSchemaName (events share the document schema). Qualified names are
  bracket-quoted [schema].[table]; bare names are the unbracketed identifier
  (matching DocumentMapping.TableName). For<T> / For(Type) cover documents and
  projection aggregates via the same pc_doc_ convention.
- Exposed as StoreOptions.SchemaResolver (named SchemaResolver, not Schema,
  because StoreOptions.Schema is already Polecat's SchemaConfiguration). Lazily
  constructed + cached.
- Wired into DescribeConfiguration: the store-usage description now carries a
  "Schema" child reporting the resolved event-store table locations — the
  schema-diagnostics surface the lift is about.

Validated:
  All projects build clean (Debug)
  Polecat.Tests Schema resolver + document_store_usage (net10.0): 11 pass / 0 fail
  (4 new resolver tests: schema names, qualified/bare event tables, document
   table by type, custom schema)

Closes #133.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…cs (consume jasperfx#334)

jasperfx#334 (PR jasperfx#346) lifted IInitialData<TStore>,
InitialDataCollection<TStore>, IConfigureStore<TOptions>, and
IAsyncConfigureStore<TOptions> to JasperFx core.

- Polecat.IInitialData now inherits JasperFx.IInitialData<IDocumentStore>
  (empty marker preserving the Polecat.IInitialData name); implementers'
  Populate(IDocumentStore, CancellationToken) satisfies the lifted member.
- Polecat.InitialDataCollection now inherits
  JasperFx.InitialDataCollection<IDocumentStore> — the lambda Add overload
  (originally Polecat's contribution) lives in the lifted base, so the empty
  subclass keeps StoreOptions.InitialData and PolecatActivator's
  `foreach (var d in InitialData) await d.Populate(store, ct)` working unchanged.
- Polecat.IConfigurePolecat now inherits JasperFx.IConfigureStore<StoreOptions>;
  the AddPolecat factory's GetServices<IConfigurePolecat>() + the
  LambdaConfigurePolecat impl bind unchanged.

Old names type-forwarded via inheritance (no rename, no source break). The
generic IConfigurePolecat<T> is Polecat-specific and out of scope (the lifted
contract is options-typed, not store-typed). The optional async configure hook
(IAsyncConfigureStore<StoreOptions>) is available but not wired — no current need.

Validated:
  All projects build clean (Debug)
  Polecat.Tests Seeding + DependencyInjection (net10.0): 22 pass / 0 fail

Closes #134.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…ion enums (consume weasel#287)

weasel#287 lifted the Hi-Lo sequence contract and the serialization storage
enums into Weasel.Core; both were member-identical between Marten/Polecat and
Weasel.Core (verified ordinal/flag values against the pinned 9.0.0-alpha.8 dll).

Part A — Hi-Lo sequence:
- HiloSequence now derives from Weasel.Core.Sequences.HiloSequenceBase, which
  owns the EntityName / CurrentHi / CurrentLo / MaxLo / Settings state, the
  NextInt/NextLong lock, AdvanceValue, ShouldAdvanceHi, and TrySetCurrentHi.
  The subclass keeps only the SQL Server I/O: AdvanceToNextHi(Sync),
  SetFloor, EnsureHiloTable*, the optimistic UPDATE/INSERT TryGetNextHi* with
  the 2627 retry, and the ResiliencePipeline wrapping. (TrySetCurrentHi now
  takes the boxed long the loop already passes.)
- Deleted Polecat.Schema.Identity.Sequences.{ISequence, IReadOnlyHiloSettings,
  HiloSettings} and Polecat.Exceptions.HiloSequenceAdvanceToNextHiAttemptsExceededException;
  global-aliased the three sequence types in src/Polecat/GlobalUsings.cs so
  SequenceFactory / StoreOptions / DocumentMapping / AdvancedOperations keep
  resolving them unqualified. Behavior unchanged (the lifted exception message
  differs only by a trailing period; no test asserts it).

Part B — serialization enums:
- Deleted Polecat.Serialization.{Casing, CollectionStorage, NonPublicMembersStorage,
  EnumStorage}; consume the Weasel.Core enums. No global EnumStorage alias (it
  would shadow files that already see Weasel.Core.EnumStorage); instead added
  `using Weasel.Core;` to the six consumers (ISerializer, Serializer, StoreOptions,
  EventDataMemberFactory, EnumMember, MemberFactory) + the serialization test.

Validated:
  All gate projects build clean (Debug): Polecat, Polecat.Tests, Polecat.AspNetCore,
  Polecat.EntityFrameworkCore(.Tests), Polecat.AotSmoke
  Polecat.Tests HiLo + serialization_configuration (net10.0): 68 pass / 0 fail

Closes #137.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…column (consume jasperfx#336, jasperfx#338)

jasperfx#338 lifted the ILongVersioned (long Version) contract; jasperfx#336 is the
fuller feature. Implemented once, closing both: documents can now track a 64-bit
revision, recommended for MultiStreamProjection-derived views whose Version is the
global event sequence number (which can climb past Int32.MaxValue).

- Detection: DocumentMapping recognizes JasperFx.ILongVersioned alongside IRevisioned —
  both set UseNumericRevisions; ILongVersioned also sets the new UseLongRevisions flag.
- Column (Decision D2 = bigint always): DocumentTable `version` is now `bigint` with no
  default (every write sets it explicitly; the old DEFAULT was dead weight and blocked
  the in-place ALTER). IRevisioned (int) values fit and are downcast on read.
- Non-destructive widening migration: DocumentTableEnsurer.WidenVersionColumnIfNeededAsync
  drops any lingering version default constraint and ALTERs an existing int column to
  bigint in place before Weasel diffs the table — never a drop/recreate, so rows survive.
  SQL Server rejects ALTER COLUMN while a default references the column and Weasel emits
  only a bare ALTER COLUMN, so the default handling lives here. Idempotent.
- Reader paths widened to GetInt64 then assign-long (ILongVersioned) / downcast-to-int
  (IRevisioned): Insert/Update/UpsertOperation.PostprocessAsync, QuerySession.SyncVersionProperties,
  DeserializingSelector, AdvancedSqlResultReader. Expected-revision plumbing (DocumentProvider
  BuildUpsert/BuildUpdate + the two operations) is now long; int callers widen implicitly.
- API: added UpdateRevision<T>(T, long) overload (IDocumentOperations + DocumentSessionBase
  + NestedTenantSession delegate). JasperFx.ConcurrencyException already covers both.
- Docs: documents/concurrency.md gains an ILongVersioned section + the int-vs-long guidance;
  storage docs updated to bigint.

Validated:
  All gate projects build clean (Debug); no new warnings
  Polecat.Tests full suite (net10.0): 1144 pass / 3 pre-existing skip / 0 fail
    (Versioning slice 27 pass — includes long_versioned_operations with a Version >
     Int32.MaxValue round-trip + concurrency, and version_column_widening_migration
     proving int->bigint preserves rows)
  Polecat.EntityFrameworkCore.Tests (net10.0): 37 pass / 0 fail (incl. forced widening path)

Closes #136 #138.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Graduates Polecat to its first release candidate on the foundation already pinned in
this branch (JasperFx 2.0.0-rc.2 / Weasel 9.0.0-alpha.8) after the #125#138 consume +
dedupe wave. (main had independently moved to 4.0.0-alpha.10; rc.1 supersedes it.)

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
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.

Adopt shared IProjectionCoordinator interface + JasperFx tenant constants

1 participant