Saltar al contenido principal
Version: 0.13.0

Roadmap

Quark is currently v0.12 — late-alpha, with Phase 6 open and actively delivering toward a v1.0 honesto. This page separates what already ships from what is planned, so the docs do not read like a promise that every idea is already in main.

The canonical roadmap (with the phased plan and trade-offs) lives at docs/ANALISIS_MADUREZ.md §4; the operational backlog lives at TASKS.md.

Implemented core (shipping today)

Type-safe builder + composable query AST

  • Type-safe Query[T] builders, immutable composition (clone-per-method).
  • Typed expression AST (Col/Lit/Func/And/Or/Not/Cast/In/Exists).
  • Subqueries composable through AsSubquery.
  • CTEs (With, WithRecursive).
  • Window functions (OVER (PARTITION BY … ORDER BY …), RowNumber/Rank/Lag).
  • Set operators: UNION, INTERSECT, EXCEPT.
  • Pessimistic locking: ForUpdate, ForShare, SkipLocked, NoWait.
  • Optimistic locking: quark:"version" tag + ErrStaleEntity.
  • HavingAggregate for HAVING over aggregates.
  • Nested Preload with dotted paths ("Orders.Items.Product").
  • IN(...) chunking respecting dialect limits (Oracle 1000, MSSQL 2100).
  • Structured JoinBuilder with ValidateJoinOn.

Six dialects + SQLGuard

  • SQLite, PostgreSQL, MySQL, MariaDB, SQL Server, Oracle dialects.
  • SQLGuard identifier, operator, raw-query, JSON path, and JOIN-ON validation.
  • Dialect-specific upserts (ON CONFLICT / ON DUPLICATE KEY / MERGE).
  • Custom dialects via RegisterDialect.

Rich types

  • Nullable[T] generic.
  • JSON[T] typed JSON column wrapper.
  • Array[T] typed array wrapper (PG native, JSON-backed elsewhere).
  • RegisterTypeMapper for extensible mapping (decimal, UUID, etc. as opt-in).
  • time.Duration mapped out of the box.
  • Per-column timezones via quark:"tz=..." tag or Client-wide WithDefaultTZ; UTC-always wire contract.

CRUD + dirty tracking + soft delete

  • Create/Update/UpdateFields/Delete/HardDelete/UpsertBatch/ CreateBatch/UpdateBatch/DeleteBatch.
  • Dirty tracking via Tracked[T]: snapshot at load, Save() emits UPDATE only over changed fields (closes the isZeroValue trap of Update(entity) for false/0/"").
  • Soft delete scopes: WithTrashed, OnlyTrashed, Restore.

Lifecycle hooks (transactional in v0.9)

  • Before/After hooks for Create / Update / Delete.
  • BeforeFind / AfterFind.
  • After* fire post-commit under Client.Tx — undone work no longer fires its side-effects.
  • Tx.OnCommit / Tx.OnRollback + quark.TxFromContext for arbitrary commit/rollback side-effects.
  • Savepoint rollback unwinds the queued hooks of that scope (v0.10).

Migrations (schema-as-code)

  • Migrate, Sync, CreateIndex, AddForeignKey.
  • Neutral schema introspection (Client.IntrospectSchema) across the four CI dialects + SQLite.
  • Pure-Go schema diff (Diff, PlanMigration, ApplyPlan) with round-trip identity: Migrate(model) → PlanMigration(model) returns empty Plan on the five CI motors.
  • Transactional or resumable execution: PG / MSSQL / SQLite transactional; MySQL / MariaDB / Oracle resumable with quark_migration_state checkpoints.
  • Distributed migration lock: PG pg_advisory_lock, MySQL/MariaDB GET_LOCK, MSSQL sp_getapplock. SQLite/Oracle return ErrUnsupportedFeature.
  • Orchestrated Backfill with PK-based batching and resume tokens in quark_backfill_state.
  • Per-Client model registry (Client.RegisterModel and friends).
  • Versioned Go migrations via github.com/jcsvwinston/quark/migrate (versioned migration registry still global — see Known boundaries).
  • quarkmigrate plan/verify/apply package (library, embeddable in your own migrations/main.go).

Multi-tenancy (four strategies)

  • DatabasePerTenant with LRU of Clients.
  • SchemaPerTenant.
  • RowLevelSecurityClient — client-side WHERE injection (all six dialects; works through Or() thanks to cloneForGroup).
  • RowLevelSecurityNative — PostgreSQL engine-enforced RLS via set_config('app.tenant_id', …, true) + CREATE POLICY. PG-only; other dialects fail-fast with ErrUnsupportedFeature. Includes the quarktenant install-rls-policies CLI to generate the policy DDL.
  • Tenant context propagation through association loads/saves.

Production caché (memory + Redis)

  • Pluggable CacheStore (memory, Redis).
  • Stampede protection: stampedeStore wrapper (singleflight + ±jitter + Vattani XFetch) — ADR-0011. Knobs: WithCacheJitter, WithCacheXFetchBeta.
  • Per-row invalidation: <table>:<pk> tag on top of the table tag; mutations register the affected PKs.
  • Deterministic, type-tagged, length-prefixed cache keys.
  • Redis tag-TTL bug fixed (NX + GT pair takes the MAX, Redis 7+).

Observability

  • OpenTelemetry traces (spans with db.statement / db.operation).
  • OpenTelemetry metrics: counter quark.queries.total, histograms quark.queries.duration and quark.queries.rows.
  • WithSpanRedaction keeps bind values out of spans by default; IncludeArgs is opt-in for local debug.
  • WithSlowQueryThreshold emits structured slow-query WARNs through Client.logger.
  • Query observers and middleware.

Transactional resilience

  • Client.Tx(...) callback API; nested savepoint-style callbacks; explicit savepoints; isolation levels.
  • WithDeadlockRetry(maxAttempts) on Client.Tx — re-runs the closure on PG 40P01 / MySQL 1213 / MSSQL 1205 / Oracle ORA-00060 with exponential backoff + jitter (opt-in, ctx-aware).

Audit log + event bus (v0.9)

  • Client.EnableAuditLog(ctx, AuditConfig) — records every Create/Update/Delete into quark_audit on the same connection/transaction as the write, atomically.
  • Client.UseEventBus(bus) — real EventBus publishing created / updated / deleted events synchronously post-commit (at-least-once, no outbox — ADR-0013).

Code generation (Phase 6, opt-in)

  • cmd/quark binary with subcommands: gen, init, inspect, migrate, model, seed, sync, tenant, validate. quark gen is generally available since v0.11.
  • Typed scanners on the read path (List/First/Find).
  • Typed INSERT binder for single-integer-PK models (Create).
  • Typed compile-time column accessors (<Model>Columns + Query.WhereP) — pure compile-time sugar; column typos and wrong-typed values fail at build time.
  • Versioned generator contract (//quark:gen vN) + model-hash drift check; incompatible-version files fall back to reflection by design.

Stored routines

  • Stored routine helpers (routine_builder.go).

In progress (Phase 6 — path to v1.0)

  • Read replicas (F6-5) — experimental: WithReplicas(replica1, …) routes multi-row reads round-robin to replicas; writes always go to the primary; Sticky(ctx) pins reads to the primary for read-your-writes. No health-checking or failover yet — a configured replica going down means failed reads on that node. See Read replicas.
  • Primary failover (F6-6) — pending. Reuses the deadlock-classifier pattern of F4-7. Will open ADR-0015 with replicas.
  • Sharding (ShardRouter, F6-7) — pending. Opens ADR-0016.
  • Stress testing harness (F6-9) — harness landed in benchmarks/stress/; PR + doc pending.
  • ent + sqlc in the benchmarks harness (F6-8b) — pending; relevant for the v1.0 codegen-tier comparison.
  • UPDATE / partial / batch binder codegen (F6-3b) — deferred; measured payoff ~1% (benchmarks/PROFILING.md).

Known current boundaries

  • Oracle is excluded from CI while the testcontainers image issue is open. Oracle-specific SQL is validated manually with a DSN env var.
  • The ADR-0002 ≥3× p99 gate is not met by scan/bind codegen (~2–5% scan, ~1% INSERT) — the per-op CPU is dominated by database/sql and the engine, not reflection. The codegen layer remains valuable for type-safety (F6-4) and forward compatibility; it is not the path to a 3× speedup. See benchmarks/PROFILING.md.
  • The versioned migration registry in migrate/migrate.go is still global. The model registry has been per-Client since v0.6 (F3-7); the versioned registry stays as documented debt.
  • LISTEN/NOTIFY listener side (PG) is not implemented in the EventBus. Notify for outbound notifications is supported; ListenerFactory.CreateListener returns ErrUnsupportedFeature.
  • Select and Where validate simple identifiers; dotted columns and SQL expressions require views or controlled raw SQL via the internal/guard layer.
  • DeleteBy and DeleteBatch are hard-delete APIs in the current implementation.
  • Bulk and WHERE-based methods (CreateBatch, UpdateBatch, DeleteBatch, DeleteBy) bypass hooks.

Long-term goals (post-v1.0)

  • Schema-first workflow with reviewable migration generation from a declarative schema (Atlas/Prisma-style). The pure-Go schema diff shipped in v0.6 is the foundation; the schema-first DSL is the next layer if demand justifies it.
  • Cross-instance stampede coordination (distributed lock hook for the cache layer). Documented in ADR-0011 §"Cuándo reabrir"; only reopened if user demand surfaces.
  • Pluggable ID strategies (UUID v7, ULID, Snowflake) as built-ins.
  • Outbound CRUD lifecycle events to NATS/Kafka/Redis Streams as out-of-the-box EventBus implementations beyond the logger/OTel defaults.
  • More database-native features behind dialect-specific extension points as the user base demands them.