Files

69 lines
4.2 KiB
Markdown

<!-- SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0 -->
# The mariadb profile
**Status (source review 2026-10-21): adapter and migration assets, not a deployable
generated app profile.** The CLI accepts MariaDB pruning, but only the Convex
selection path rewrites the root runtime/deployment composition. The web/worker
roots have no MySQL composition, and the previously described profile config
file is absent. The platform injects `DATABASE_URL`; these draft assets still
name `MARIADB_URL`, so their variable contract also needs reconciliation.
The tables and generated-app steps below describe the target design. Adapter
and migration-engine tests do not establish a generated application deployment.
The persistence profile for an app whose primary store is MariaDB instead of Postgres
(spec §5.1): the same procedures, the same modules, the same migrations discipline, on the
Kysely MySQL dialect (`@conusai-kit/data-kysely/mysql`) with jobs on BullMQ over Valkey
(`@conusai-kit/jobs-bullmq`).
| | postgres (default) | mariadb (this profile) |
|---|---|---|
| Primary store | Postgres 18 | MariaDB LTS |
| Data adapter | `@conusai-kit/data-kysely` | `@conusai-kit/data-kysely/mysql` |
| Jobs | pg-boss (Postgres) | BullMQ on Valkey (`@conusai-kit/jobs-bullmq`) |
| Tenant wall | repository predicate + RLS (three roles, AT-D20) | repository predicate alone — MariaDB has no RLS |
| Links | `postgres`, `identity` | `mariadb`, `redis`, `identity` |
| Process env | `POSTGRES_URL`, `POSTGRES_READER_URL`, `POSTGRES_MIGRATE_URL` | `MARIADB_URL`, `REDIS_URL` |
## What this folder carries
- `conusai.json` — the profile's deployment contract: the same three services, links
`mariadb` + `redis` + `identity`. There is no `mariadb.migrate` flag: the three-role split it
declares on Postgres (data-services DS21) exists to make row-level security bind, and MariaDB
has none, so every process holds the one `MARIADB_URL` and ordering is compose's
`service_completed_successfully` alone (AT-D14).
- `compose.yaml`, `compose.dev.yaml` — the profile's compose files. The dev overlay runs
`mariadb:lts` and `valkey/valkey:9-alpine`, the images the platform's catalog offers.
- `migrations/` — the kernel tables (tenancy, sign-in, files, proposals, outbox, idempotency
keys) as MariaDB DDL, generated by `mysqlSchemaStatements` from the same entity definitions as
the postgres files and committed, forward-only. A module's own MariaDB migrations live with the
module: `modules/<id>/adapters/kysely/mysql/migrations/`, declared in its manifest as
`migrations: { postgres: "migrations", mariadb: "adapters/kysely/mysql/migrations" }`.
## Target generated-app changes (not wired)
The profile is chosen at generation time (`.conusai/template.json` `profile`), and
`kit template:prune --profile mariadb` removes the other dialects. Concretely:
1. `config/src/env.ts` reads `MARIADB_URL` (every process) instead of the three Postgres URLs —
one login, because there is no RLS to bind (AT-D20 is Postgres-only).
2. `apps/web` and `apps/worker` compose `createMysqlDataSource` (Kysely `MysqlDialect` + `mysql2`)
and the worker's queue is `createBullmqJobQueue`/`createBullmqWorker` over `REDIS_URL`.
3. The migrate job runs `runMysqlMigrationsFromEnv` over `profiles/mariadb/migrations/` (moved to
`migrations/mariadb/`) and the modules' `adapters/kysely/mysql/migrations/`.
4. This folder's `conusai.json`, `compose.yaml` and `compose.dev.yaml` replace the root ones.
The dialect differences are explicit, never generated at run time (spec §5.3): a module's MariaDB
schema is its own numbered SQL folder, reviewed like any migration.
## Proof
- `@conusai-kit/data-kysely`'s MySQL dialect passes the shared repository and capability contract
suites against `mariadb:lts` in testcontainers — the tenant predicate is the wall, and the
contract is what proves it.
- `@conusai-kit/jobs-bullmq` passes the shared JobQueue contract against `valkey/valkey:9` in
testcontainers.
- `scripts/vendor/test-template.sh app --profile mariadb` runs the template's gate and then
applies this folder's and the modules' MariaDB migrations to a real MariaDB LTS container, so
the committed DDL is proven against the engine, not just generated.