mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-01-23 02:36:05 +00:00
test(sync): add canary test for entity type coverage
Add safeguards to prevent silent failures when new entity types are added without proper registration: - Add canary test that fails if EntityType union grows but test arrays aren't updated (verifies count matches expected 20 types) - Create developer checklist at docs/ai/adding-new-entity-type-checklist.md documenting all required changes when adding new entity types
This commit is contained in:
parent
16d2ba1f25
commit
30fa62b9a4
2 changed files with 106 additions and 0 deletions
82
docs/ai/adding-new-entity-type-checklist.md
Normal file
82
docs/ai/adding-new-entity-type-checklist.md
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
# Adding New Entity Types Checklist
|
||||
|
||||
This checklist ensures new entity types integrate properly with the operation log and sync system.
|
||||
|
||||
## When adding a new entity type:
|
||||
|
||||
### 1. Type Definition (`src/app/core/persistence/operation-log/operation.types.ts`)
|
||||
|
||||
- [ ] Add to `EntityType` union (line ~15)
|
||||
|
||||
### 2. Entity Registry (`src/app/core/persistence/operation-log/entity-registry.ts`)
|
||||
|
||||
- [ ] Add entry to `ENTITY_CONFIGS` with:
|
||||
- `storagePattern`: 'adapter' | 'singleton' | 'map' | 'array' | 'virtual'
|
||||
- `featureName`: NgRx feature key
|
||||
- `payloadKey`: Key used in sync/import payloads
|
||||
- Appropriate selectors for the storage pattern:
|
||||
- **adapter**: `selectEntities`, `selectById`, `adapter`
|
||||
- **singleton**: `selectState`
|
||||
- **map**: `selectState`, `mapKey`
|
||||
- **array**: `selectState`, `arrayKey`
|
||||
- **virtual**: just `payloadKey`
|
||||
|
||||
### 3. Test Arrays (`src/app/core/persistence/operation-log/entity-registry.spec.ts`)
|
||||
|
||||
- [ ] Add to `REGULAR_ENTITY_TYPES` array (line ~17) OR `SPECIAL_OPERATION_TYPES` if special
|
||||
- [ ] Add to appropriate category array:
|
||||
- `ADAPTER_ENTITIES`
|
||||
- `SINGLETON_ENTITIES`
|
||||
- `MAP_ENTITIES`
|
||||
- `ARRAY_ENTITIES`
|
||||
- `VIRTUAL_ENTITIES`
|
||||
- [ ] Update expected count in canary test (look for `expect(ALL_TESTED.length).toBe(...)`)
|
||||
|
||||
### 4. Meta-Reducers (if entity has relationships)
|
||||
|
||||
- [ ] Add cascade delete logic in appropriate meta-reducer under `src/app/root-store/meta/task-shared-meta-reducers/`
|
||||
- [ ] Register meta-reducer in `META_REDUCERS` array in `src/app/root-store/meta/meta-reducer-registry.ts`
|
||||
|
||||
## When adding bulk actions:
|
||||
|
||||
Bulk actions operate on multiple entities atomically. Required setup:
|
||||
|
||||
- [ ] Set `isBulk: true` in action meta
|
||||
- [ ] Use `entityIds` array (not single `entityId`)
|
||||
- [ ] Ensure action has `isPersistent: true` and correct `entityType`
|
||||
|
||||
Example:
|
||||
|
||||
```typescript
|
||||
updateTasks: (taskProps: { tasks: Update<Task>[] }) => ({
|
||||
...taskProps,
|
||||
meta: {
|
||||
isPersistent: true,
|
||||
entityType: 'TASK',
|
||||
entityIds: taskProps.tasks.map((t) => t.id as string),
|
||||
opType: OpType.Update,
|
||||
isBulk: true, // Required for bulk operations
|
||||
} satisfies PersistentActionMeta,
|
||||
}),
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
# Check the modified files
|
||||
npm run checkFile src/app/core/persistence/operation-log/entity-registry.ts
|
||||
npm run checkFile src/app/core/persistence/operation-log/operation.types.ts
|
||||
|
||||
# Run the entity registry tests
|
||||
npm run test:file src/app/core/persistence/operation-log/entity-registry.spec.ts
|
||||
```
|
||||
|
||||
## Why this matters
|
||||
|
||||
The operation log system depends on hardcoded registries to:
|
||||
|
||||
- Convert actions to operations and back
|
||||
- Apply remote operations during sync
|
||||
- Handle cascade deletes atomically
|
||||
|
||||
Missing or incomplete registrations cause **silent failures** - operations may not replay correctly on other devices.
|
||||
|
|
@ -410,5 +410,29 @@ describe('entity-registry', () => {
|
|||
expect(REGULAR_ENTITY_TYPES).toContain(key as EntityType);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* CANARY TEST: This test ensures test arrays stay in sync with EntityType union.
|
||||
* If you add a new entity type to EntityType in operation.types.ts, you MUST also:
|
||||
* 1. Add it to REGULAR_ENTITY_TYPES or SPECIAL_OPERATION_TYPES above
|
||||
* 2. Add it to the appropriate category array (ADAPTER_ENTITIES, SINGLETON_ENTITIES, etc.)
|
||||
* 3. Update the expected count below
|
||||
*
|
||||
* See docs/ai/adding-new-entity-type-checklist.md for full checklist.
|
||||
*/
|
||||
it('test arrays should cover all EntityType union members (canary)', () => {
|
||||
const ALL_TESTED: EntityType[] = [
|
||||
...REGULAR_ENTITY_TYPES,
|
||||
...SPECIAL_OPERATION_TYPES,
|
||||
];
|
||||
|
||||
// Update this count when adding new entity types to EntityType union
|
||||
// Current: 17 regular + 3 special = 20 total
|
||||
expect(ALL_TESTED.length).toBe(20);
|
||||
|
||||
// Verify no duplicates
|
||||
const uniqueTypes = new Set(ALL_TESTED);
|
||||
expect(uniqueTypes.size).toBe(ALL_TESTED.length);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue