R1: schema & naming reset — squash migrations, rename variants
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 11s
CI / ui (pull_request) Successful in 37s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m8s

Squash the 12 goose migrations into one 00001_baseline.sql (there is no prod
data; verified schema-identical to the chain via a pg_dump diff + the green
integration suite) and rename the game-variant labels
english/russian_scrabble/erudit -> scrabble_en/scrabble_ru/erudit_ru across the
backend, the FlatBuffers wire values and the UI.

dawg filenames and the Go enum identifiers are unchanged; the i18n display keys
are kept. Adds PRERELEASE.md (the R1-R7 pre-release tracker), linked from
CLAUDE.md. Contour DB wipe and the scrabble-dictionary tidy are follow-ups.
This commit is contained in:
Ilia Denisov
2026-06-09 12:09:50 +02:00
parent 70e3fab512
commit 26aa154547
54 changed files with 688 additions and 675 deletions
+20 -20
View File
@@ -12,37 +12,37 @@ import {
// The cache module is per-file-isolated by vitest, so only what these tests seed exists.
describe('alphabet cache (Stage 13)', () => {
it('upper-cases letters for display and maps indices and values case-insensitively', () => {
setAlphabet('english', [
setAlphabet('scrabble_en', [
{ index: 0, letter: 'a', value: 1 },
{ index: 16, letter: 'q', value: 10 },
]);
expect(hasAlphabet('english')).toBe(true);
expect(letterForIndex('english', 0)).toBe('A');
expect(letterForIndex('english', 16)).toBe('Q');
expect(indexForLetter('english', 'a')).toBe(0);
expect(indexForLetter('english', 'Q')).toBe(16);
expect(valueForLetter('english', 'a')).toBe(1);
expect(valueForLetter('english', 'Q')).toBe(10);
expect(hasAlphabet('scrabble_en')).toBe(true);
expect(letterForIndex('scrabble_en', 0)).toBe('A');
expect(letterForIndex('scrabble_en', 16)).toBe('Q');
expect(indexForLetter('scrabble_en', 'a')).toBe(0);
expect(indexForLetter('scrabble_en', 'Q')).toBe(16);
expect(valueForLetter('scrabble_en', 'a')).toBe(1);
expect(valueForLetter('scrabble_en', 'Q')).toBe(10);
});
it('handles the blank sentinel and unknown letters/indices', () => {
setAlphabet('english', [{ index: 0, letter: 'a', value: 1 }]);
expect(letterForIndex('english', BLANK_INDEX)).toBe('?');
expect(indexForLetter('english', '?')).toBe(BLANK_INDEX);
expect(valueForLetter('english', '?')).toBe(0);
expect(letterForIndex('english', 99)).toBe(''); // out of range
expect(valueForLetter('english', 'Z')).toBe(0); // not in this alphabet
expect(() => indexForLetter('english', 'Z')).toThrow();
setAlphabet('scrabble_en', [{ index: 0, letter: 'a', value: 1 }]);
expect(letterForIndex('scrabble_en', BLANK_INDEX)).toBe('?');
expect(indexForLetter('scrabble_en', '?')).toBe(BLANK_INDEX);
expect(valueForLetter('scrabble_en', '?')).toBe(0);
expect(letterForIndex('scrabble_en', 99)).toBe(''); // out of range
expect(valueForLetter('scrabble_en', 'Z')).toBe(0); // not in this alphabet
expect(() => indexForLetter('scrabble_en', 'Z')).toThrow();
});
it('lists the alphabet for the blank chooser and is empty for an uncached variant', () => {
setAlphabet('english', [
setAlphabet('scrabble_en', [
{ index: 0, letter: 'a', value: 1 },
{ index: 1, letter: 'b', value: 3 },
]);
expect(alphabetLetters('english')).toEqual(['A', 'B']);
expect(hasAlphabet('erudit')).toBe(false);
expect(alphabetLetters('erudit')).toEqual([]);
expect(valueForLetter('erudit', 'A')).toBe(0);
expect(alphabetLetters('scrabble_en')).toEqual(['A', 'B']);
expect(hasAlphabet('erudit_ru')).toBe(false);
expect(alphabetLetters('erudit_ru')).toEqual([]);
expect(valueForLetter('erudit_ru', 'A')).toBe(0);
});
});