feat(api): add hp_regen_since column for persistent HP regeneration
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
export class AddHpRegeneration1792000000000 implements MigrationInterface {
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
'ALTER TABLE "characters" ADD COLUMN "hp_regen_since" TIMESTAMP WITH TIME ZONE',
|
||||
);
|
||||
|
||||
// Existing characters start regenerating immediately from their current
|
||||
// HP. A character whose fight is still ACTIVE keeps regeneration paused
|
||||
// until that fight resolves, matching the "no combat-time regen" rule
|
||||
// (persistent-hp-and-regeneration design, R4) -- this migration must not
|
||||
// gift them free healing mid-fight.
|
||||
await queryRunner.query('UPDATE "characters" SET "hp_regen_since" = now()');
|
||||
await queryRunner.query(`UPDATE "characters" AS "character"
|
||||
SET "hp_regen_since" = NULL
|
||||
FROM "combats" AS "combat"
|
||||
WHERE "combat"."character_id" = "character"."id"
|
||||
AND "combat"."status" = 'ACTIVE'`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('ALTER TABLE "characters" DROP COLUMN "hp_regen_since"');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import 'reflect-metadata';
|
||||
import { getMetadataArgsStorage } from 'typeorm';
|
||||
import { Character } from '../../characters/entities/character.entity';
|
||||
|
||||
describe('characters.hp_regen_since schema', () => {
|
||||
it('stores the regeneration anchor as a nullable timestamptz', () => {
|
||||
const metadata = getMetadataArgsStorage();
|
||||
const column = metadata.columns.find(
|
||||
(candidate) =>
|
||||
candidate.target === Character && candidate.propertyName === 'hpRegenSince',
|
||||
);
|
||||
|
||||
expect(column).toBeDefined();
|
||||
expect(column?.options.type).toBe('timestamptz');
|
||||
expect(column?.options.nullable).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user