mirror of
https://github.com/hanzoai/chat.git
synced 2026-09-30 20:51:17 +00:00
The Mongo->SQLite cutover finished. chat-docdb is deleted, MONGO_URI is unset,
and all 29 domains are served from the embedded SQLite file on the PVC. What was
left behind was scaffolding that reads as live.
- Remove the CHAT_STORE_DUALWRITE seam. Phase 4 is done: the flag is unset in
the live container, and with it unset applySqliteOverrides never constructed a
DualWriteModel anyway. The mirror existed to keep Mongo current as a rollback
target and there is no Mongo to roll back to, so the escape hatch was already
unusable. DualWriteModel + its spec, the export, the flag branch, and the
stale comments in Role/Transaction/token/session all go.
- Drop `logger.info('Connected to MongoDB')`. It fired unconditionally one line
after connectDb() logged that it was skipping Mongo, so the boot log asserted
a connection that had just been declined.
- Retarget the authStore SQLite spec from DualWriteModel to DocModel rather than
deleting it. It is the regression proof for the P1 that broke cold logins; the
coverage is worth keeping, only the model shape changed.
- Rewrite the LLM.md store section, which still described Mongo as the live
parallel store and told the reader that ripping it means data loss.
express-mongo-sanitize STAYS, and the comment above it now says why: the SQLite
engine still interprets $eq/$ne/$in/$or/$regex in filters and $set/$inc/$push in
updates, so a {"$ne": null} reaching a filter is operator injection against
SQLite exactly as it was against Mongo. The guard outlived the database it is
named for. mongoose, mongoMeili and keyvMongo also stay -- see LLM.md for why
each is a migration rather than a sweep.
Verified: data-schemas rollup build clean, DualWrite absent from the bundle,
createModels resolves flagged collections to DocModel and unflagged to mongoose.
Store suite is identical to origin/main (same 5 pre-existing meili failures,
minus exactly the 10 dual-write tests removed).
Co-authored-by: Hanzo Dev <[email protected]>
65 lines
2.5 KiB
JavaScript
65 lines
2.5 KiB
JavaScript
/**
|
|
* CI test runner for @hanzochat/data-schemas.
|
|
*
|
|
* The spec files listed in ISOLATED instantiate the native `better-sqlite3-*`
|
|
* driver. Jest gives every spec file its own JS module realm, but the native
|
|
* addon is process-cached per worker, so cross-file state corrupts sibling
|
|
* in-memory databases (driver-agnostic — reproduces with mainstream
|
|
* better-sqlite3 too; a compound `json_extract` UNIQUE stops firing). Production
|
|
* is unaffected: it runs one module realm with one shared handle for the process
|
|
* lifetime. The fix is strict one-file-per-process isolation for those specs
|
|
* only — NOT `--runInBand`/`--maxWorkers=1` (a single shared worker still
|
|
* corrupts). Everything else runs in the normal coverage pass.
|
|
*/
|
|
import { spawnSync } from 'node:child_process';
|
|
import { createRequire } from 'node:module';
|
|
import { dirname, join } from 'node:path';
|
|
|
|
const require = createRequire(import.meta.url);
|
|
const JEST = join(dirname(require.resolve('jest/package.json')), 'bin', 'jest.js');
|
|
|
|
/** Native-driver specs — each run in its own process. */
|
|
const ISOLATED = [
|
|
'src/stores/sqlite/DocModel.spec.ts',
|
|
'src/stores/sqlite/meili.sqlite.spec.ts',
|
|
'src/models/storeRegistry.spec.ts',
|
|
'src/models/plugins/tenantIsolation.coverage.spec.ts',
|
|
'src/methods/convoMessage.sqlite.spec.ts',
|
|
'src/methods/distinct.sqlite.spec.ts',
|
|
'src/methods/skill.harness.sqlite.spec.ts',
|
|
'src/methods/batch2.sqlite.spec.ts',
|
|
'src/methods/batch3.sqlite.spec.ts',
|
|
'src/methods/batch4.sqlite.spec.ts',
|
|
'src/methods/batch5.sqlite.spec.ts',
|
|
'src/methods/batch6.sqlite.spec.ts',
|
|
'src/methods/batch7.sqlite.spec.ts',
|
|
'src/methods/batch7b.sqlite.spec.ts',
|
|
'src/methods/batch8a.sqlite.spec.ts',
|
|
'src/methods/batch8b.sqlite.spec.ts',
|
|
'src/methods/authStore.sqlite.spec.ts',
|
|
];
|
|
|
|
const runJest = (args) =>
|
|
spawnSync(process.execPath, [JEST, '--ci', ...args], { stdio: 'inherit' }).status === 0;
|
|
|
|
const escapeRegExp = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
|
|
let ok = true;
|
|
|
|
// 1) Normal coverage run for everything except the isolated set.
|
|
console.log(`\n[ci] coverage run (excluding ${ISOLATED.length} native-driver specs)`);
|
|
const ignore = ['/node_modules/', ...ISOLATED.map((f) => escapeRegExp(f) + '$')];
|
|
if (!runJest(['--coverage', '--testPathIgnorePatterns', ...ignore])) {
|
|
ok = false;
|
|
}
|
|
|
|
// 2) Each native-driver spec in its own process.
|
|
for (const file of ISOLATED) {
|
|
console.log(`\n[ci] isolated: ${file}`);
|
|
if (!runJest([file])) {
|
|
ok = false;
|
|
}
|
|
}
|
|
|
|
process.exit(ok ? 0 : 1);
|