Band Lineup 1.12.0: Sync keeps your moves and puts each person in one spot
Two Sync problems found by checking the real October 25 plan against the board: - Someone on the plan twice (Mike Powell is Leader and Guitar [Acoustic]) could fill two spots, pushing a real player off the board. Which spot the duplicate took depended on the order Planning Center returned people, so it only happened some weeks. Assignment now uses each person once. - Moving a synced person to another spot was undone by the next Sync, which re-placed everyone it had filled. A move is now a hand placement for the current plan and Sync leaves it alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -128,7 +128,11 @@ function assignMembersToSlots(slots, members) {
|
|||||||
if (score > bestScore) { bestScore = score; bestIndex = i; }
|
if (score > bestScore) { bestScore = score; bestIndex = i; }
|
||||||
}
|
}
|
||||||
if (bestIndex < 0) return null;
|
if (bestIndex < 0) return null;
|
||||||
return pool.splice(bestIndex, 1)[0];
|
const chosen = pool.splice(bestIndex, 1)[0];
|
||||||
|
// One spot per person: someone scheduled twice (Leader + Acoustic) must not fill a second spot.
|
||||||
|
const key = chosen.personId || '';
|
||||||
|
if (key) for (let i = pool.length - 1; i >= 0; i -= 1) if (pool[i].personId === key) pool.splice(i, 1);
|
||||||
|
return chosen;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,3 +65,12 @@ console.log('assignment:', JSON.stringify(out));
|
|||||||
assert.strictEqual(bestLibraryMatch('Chris Smith', [{ id: '1', name: 'Chris' }, { id: '2', name: 'Chris' }]), null, 'ambiguous tie → null');
|
assert.strictEqual(bestLibraryMatch('Chris Smith', [{ id: '1', name: 'Chris' }, { id: '2', name: 'Chris' }]), null, 'ambiguous tie → null');
|
||||||
console.log('bestLibraryMatch: all assertions passed ✓');
|
console.log('bestLibraryMatch: all assertions passed ✓');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- one spot per person: someone scheduled twice (Leader + Acoustic) fills one spot only ---
|
||||||
|
{
|
||||||
|
const P = (label, name, personId) => ({ label, name, personId });
|
||||||
|
const slots = ['[LEADER, VOX 1, ACOUSTIC] MIX 1', '[GUITAR, 2] MIX 7'];
|
||||||
|
const got = assignMembersToSlots(slots, [P('[Leader]', 'Mike', 'mp'), P('Guitar [Acoustic]', 'Mike', 'mp'), P('Guitar [Rhythm]', 'Craig', 'cs')]).map((m) => (m ? m.name : null));
|
||||||
|
assert.deepStrictEqual(got, ['Mike', 'Craig'], 'Mike once, Craig gets the guitar spot');
|
||||||
|
console.log('one spot per person: all assertions passed ✓');
|
||||||
|
}
|
||||||
|
|||||||
@@ -530,8 +530,8 @@ module.exports = {
|
|||||||
const openIdx = []; const manualNames = new Set();
|
const openIdx = []; const manualNames = new Set();
|
||||||
for (let i = 0; i < eff.length; i += 1) {
|
for (let i = 0; i < eff.length; i += 1) {
|
||||||
const e = board[String(i)];
|
const e = board[String(i)];
|
||||||
if (e && (e.personId || e.name) && e.plan === planId) {
|
if (e && (e.personId || e.name || e.pco) && e.plan === planId) {
|
||||||
const nm = e.personId ? (library[e.personId] && library[e.personId].name) : e.name;
|
const nm = e.pco ? e.pco.name : e.personId ? (library[e.personId] && library[e.personId].name) : e.name;
|
||||||
if (nm) manualNames.add(normName(nm));
|
if (nm) manualNames.add(normName(nm));
|
||||||
} else openIdx.push(i);
|
} else openIdx.push(i);
|
||||||
}
|
}
|
||||||
@@ -675,6 +675,10 @@ module.exports = {
|
|||||||
const from = String(p.get('from') || ''); const to = String(p.get('to') || '');
|
const from = String(p.get('from') || ''); const to = String(p.get('to') || '');
|
||||||
if (!/^\d+$/.test(from) || !/^\d+$/.test(to) || from === to) return json(res, 400, { error: 'Bad move.' });
|
if (!/^\d+$/.test(from) || !/^\d+$/.test(to) || from === to) return json(res, 400, { error: 'Bad move.' });
|
||||||
const a = current.board[from]; const b = current.board[to];
|
const a = current.board[from]; const b = current.board[to];
|
||||||
|
// Moving a spot is a hand placement for this plan: Sync must not move it back.
|
||||||
|
const plan = current.planId();
|
||||||
|
if (a) a.plan = plan;
|
||||||
|
if (b) b.plan = plan;
|
||||||
if (a === undefined) delete current.board[to]; else current.board[to] = a;
|
if (a === undefined) delete current.board[to]; else current.board[to] = a;
|
||||||
if (b === undefined) delete current.board[from]; else current.board[from] = b;
|
if (b === undefined) delete current.board[from]; else current.board[from] = b;
|
||||||
current.saveBoard(); current.rebuildLocal();
|
current.saveBoard(); current.rebuildLocal();
|
||||||
|
|||||||
Reference in New Issue
Block a user