Rules Hub
Coding Rules Library
Rule priority, scope & exceptions
Use this to align rules with the senior-level structure (P0/P1/P2, scope, exceptions/tradeoffs).
Verify field names against the actual writer of a shared cache blob, not just your own interface
When one service writes a JSON blob to a shared store (Redis, a queue payload, etc.) that another service reads, don't trust that your reader-side TypeScript interface matches what the writer actually produces — check the writer's real serialization code. A field-name mismatch on data parsed from untyped JSON doesn't raise a type error, it just quietly resolves to undefined.
Bad example
| 1 | interface CachedAuthor { id: string; fullname: string; imageUrl: string; } |
| 2 |
|
| 3 | const data = JSON.parse(await redis.get(`author:${id}`)) as CachedAuthor; |
| 4 | const avatar = data.imageUrl; // writer actually serializes this as `profileImage` |
Explanation (EN)
The `as CachedAuthor` cast doesn't validate anything — it just tells TypeScript to trust a shape that doesn't match what was actually written, so `imageUrl` silently comes back undefined for every record.
Objašnjenje (HR)
`as CachedAuthor` cast ne validira ništa — samo govori TypeScriptu da vjeruje obliku koji se ne poklapa sa stvarno zapisanim podacima, pa `imageUrl` tiho uvijek vraća undefined.
Good example
| 1 | // checked against the writer's Author.normalizedJSON() — the real key is profileImage |
| 2 | interface CachedAuthor { id: string; fullname: string; profileImage: string; } |
| 3 |
|
| 4 | const data = JSON.parse(await redis.get(`author:${id}`)) as CachedAuthor; |
| 5 | const avatar = data.profileImage; |
Explanation (EN)
The interface was verified against the actual producer's serialization, so the field name matches what's really on the wire.
Objašnjenje (HR)
Sučelje je provjereno prema stvarnoj serijalizaciji producenta podataka, pa se naziv polja poklapa s onim što se stvarno šalje.