Seed only what the tests need, and record that it did not speed anything up

Doctrine prescribes a connected seed that writes only what is needed, because
it is linear in documents. Verified safe before applying: no step asserts on a
seeded participation -- a scenario SETS its starting participant count on the
event and reads it back -- and no profile is looked up by name. So three
profiles instead of fourteen, and no participations.

The speed argument for it was REFUTED by measurement: 24 documents took 13.3s,
eight took 20.2s. Main writes 24 in 1.4s on the same accumulated wallet, so
neither document count nor accumulation is what dominates. Main adds into one
already-open graph; this branch opens a document and a fresh subscription per
event, which is what the Refine provider's create does. The cost is in opening
documents, not in writing triples.

Kept anyway, on the justification that survives: it writes less into a wallet
nothing ever empties.
This commit is contained in:
Sylvain Duchesne
2026-09-21 15:52:31 +02:00
parent ff285455d2
commit 20b3ef8712
2 changed files with 26 additions and 24 deletions
+8 -5
View File
@@ -23,11 +23,14 @@
* for the gate's purpose (stopping the dev seed from bloating a persistent
* wallet) and is therefore left out until someone actually wants to opt in.
*
* `fixtureSeedEnabled()` BELOW IS NOT ENFORCED in `bootstrapWallet` here. On
* ng-eventually it switches every route off, which stands down the @data
* scenarios that seed; adopting that is a product decision, not a side effect of
* recovering this file. Until it is taken, only the AUTOMATIC seed is gated — an
* explicit `loadTestData()` still writes.
* `fixtureSeedEnabled()` BELOW IS DELIBERATELY NOT ENFORCED in `bootstrapWallet`
* here, and it is not a decision left pending: the intent behind it — stated
* 2026-09-21 — was to stop the dev app from creating fixtures BY ITSELF, and
* using fixtures in TESTS was never a problem. `autoSeedEnabled()` above is
* exactly that intent. The master switch overshoots it, because it also silences
* an explicit `loadTestData()`; on ng-eventually that cost the @data suite its
* fixtures (a caveat still open there). So the gate that governs the automatic
* seed is the one wired, and an explicit seed still writes.
*/
/**
+18 -19
View File
@@ -84,9 +84,19 @@ export async function bootstrapWallet(
const graph = await ensureGraphNuri(ngUsers, ngParticipations);
console.log('[Bootstrap] Using graph NURI:', graph);
// Seed users — one at a time with ORM flush between each
// Seed users — one at a time with ORM flush between each.
//
// ONLY A FEW, not all fourteen. The connected seed is LINEAR in the number of
// documents (one document per entity, each a serial round trip), so it writes
// only what is needed. Nothing in the @data layer looks a seeded profile up by
// name; what it needs is that SOME profile exists — one to answer
// `currentUserId`, and a non-empty set for "the wallet contains users". The
// first three are kept rather than one, so a participants list has somebody to
// show, and `@mariedupont` is among them because `FestipodDataContext` falls
// back to her when the account layer has not resolved.
const SEEDED_PROFILES = 3;
const userIdMap = new Map<string, string>();
for (const u of seedUsers) {
for (const u of seedUsers.slice(0, SEEDED_PROFILES)) {
ngUsers.add({
"@graph": graph,
"@type": "http://festipod.org/UserProfile",
@@ -122,23 +132,12 @@ export async function bootstrapWallet(
}
console.log('[Bootstrap] Seeded', eventIdMap.size, 'events');
// Seed participations with mapped IDs — one at a time
let partCount = 0;
for (const p of seedParticipations) {
const eventIri = eventIdMap.get(p.eventId) || p.eventId;
const userIri = userIdMap.get(p.userId) || p.userId;
ngParticipations.add({
"@graph": graph,
"@type": "http://festipod.org/Participation",
"@id": "",
event: eventIri,
user: userIri,
isConfirmed: p.isConfirmed,
} as FpParticipation);
await flushAndWait();
partCount++;
}
console.log('[Bootstrap] Seeded', partCount, 'participations');
// NO PARTICIPATIONS. The sign-up scenarios create theirs live, which is the
// behaviour they exist to exercise, and nothing asserts on a seeded one: a
// scenario's starting participant count is SET on the event
// (`updateEvent({ participantCount })`) and read back from it, never counted
// from Participation documents. Writing five here would cost five more serial
// round trips to furnish something no test looks at.
return { seeded: true, userIdMap, eventIdMap };
}