Add system ID prefix to all Redis keys to prevent cross-system ID clashes

When multiple university systems share the same Redis instance, entity IDs
(shuttles, stops, routes, etc.) could collide. This namespaces all Redis
keys with the system ID (e.g., `1:shuttle:stop:123` instead of
`shuttle:stop:123`).

- Add systemId field and prefixKey() helper to BaseRedisRepository
- Update all Redis repository subclasses to use prefixed keys
- Wire system ID from InterchangeSystem.build() into Redis repositories
- Add migration utility (migrateRedisKeysToSystemPrefix) with tests
- Update all test holders to pass a test system ID

https://claude.ai/code/session_012Vfz1NHWJbVtoDEWcE5tq6
This commit is contained in:
Claude
2026-03-23 23:17:13 +00:00
parent 4764ee6af0
commit 6d66e8f25b
15 changed files with 201 additions and 34 deletions

View File

@@ -1,3 +1,4 @@
import { RedisClientType } from 'redis';
import { TupleKey } from '../../types/TupleKey';
import {
Listener,
@@ -7,14 +8,22 @@ import {
ScheduledNotification
} from "./NotificationRepository";
import { BaseRedisRepository } from "../BaseRedisRepository";
import createRedisClientForRepository from '../../helpers/createRedisClientForRepository';
export class RedisNotificationRepository extends BaseRedisRepository implements NotificationRepository {
private notificationListeners: Listener[] = [];
private readonly NOTIFICATION_KEY_PREFIX = 'notification:';
constructor(
redisClient: RedisClientType = createRedisClientForRepository(),
systemId: string = '',
) {
super(redisClient, systemId);
}
private getNotificationKey = (shuttleId: string, stopId: string): string => {
const tuple = new TupleKey(shuttleId, stopId);
return `${this.NOTIFICATION_KEY_PREFIX}${tuple.toString()}`;
return this.prefixKey(`${this.NOTIFICATION_KEY_PREFIX}${tuple.toString()}`);
};
public addOrUpdateNotification = async (notification: ScheduledNotification): Promise<void> => {