Files
moeka-project/server/apps/api/drizzle/meta/_journal.json
T
RainbowBird 88625a8d84 feat(api): hot-reload ConfigKV from Postgres (#2289)
## Summary

- Add the `config_kv` schema and Drizzle migration `0020`.
- Keep the ConfigKV schema, cache store, and invalidation contract in
the Resource API.
- Read ConfigKV through a five-minute Redis cache with PostgreSQL
fallback.
- Reload Router and TTS voice state through `configkv:invalidate`.
- Keep Auth rate limits fixed at 20 requests per 60 seconds.

## Stack

- Depends on #2294 for the Redis test implementation.
- This PR adds ConfigKV-specific cache-aside and Pub/Sub tests on top of
that implementation.

## Deployment

Run migration `0020` before this runtime reaches production traffic.

Then freeze ConfigKV writes. Audit and backfill the data with
[proj-airi/backend#2](https://github.com/proj-airi/backend/pull/2).
Merge
[proj-airi/backend#4](https://github.com/proj-airi/backend/pull/4)
first, so
the fixed Auth rate-limit keys are skipped.

Keep writes frozen until the hashes match and two API instances pass the
Pub/Sub reload check. This PR does not run production DDL or data
migration.

## Verification

- `pnpm exec vitest run <ConfigKV cache store, sync subscriber, and Auth
rate-limit tests>` (12 tests passed)
- `pnpm -F @proj-airi/api-server typecheck`
- `git diff --check`

See #2294 for its frozen-install, ESLint, and 73-test verification.

## Visual changes

None. This PR changes backend persistence and rate-limit wiring only.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Added centralized configuration storage with validation, caching,
refresh, and automatic synchronization across services.
- Configuration updates now refresh related language-model and
text-to-speech settings automatically.

- **Bug Fixes**
- Improved recovery after service reconnects by clearing stale
configuration and reloading current values.
- Invalid or unavailable configuration data now produces clearer
service-unavailable responses.

- **Changes**
- Authentication rate limiting now uses a consistent limit of 20
requests per minute per client.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: RainbowBird <git@luoling.moe>
Signed-off-by: RainbowBird <rbxin2003@outlook.com>
2026-08-15 22:24:32 +08:00

153 lines
3.0 KiB
JSON

{
"version": "7",
"dialect": "postgresql",
"entries": [
{
"idx": 0,
"version": "7",
"when": 1772532674887,
"tag": "0000_mean_slipstream",
"breakpoints": true
},
{
"idx": 1,
"version": "7",
"when": 1772532802115,
"tag": "0001_magenta_skrulls",
"breakpoints": true
},
{
"idx": 2,
"version": "7",
"when": 1772634952890,
"tag": "0002_mean_tigra",
"breakpoints": true
},
{
"idx": 3,
"version": "7",
"when": 1773229668722,
"tag": "0003_old_titania",
"breakpoints": true
},
{
"idx": 4,
"version": "7",
"when": 1773421458174,
"tag": "0004_bouncy_devos",
"breakpoints": true
},
{
"idx": 5,
"version": "7",
"when": 1774582846222,
"tag": "0005_tough_living_tribunal",
"breakpoints": true
},
{
"idx": 6,
"version": "7",
"when": 1774584037626,
"tag": "0006_overconfident_susan_delgado",
"breakpoints": true
},
{
"idx": 7,
"version": "7",
"when": 1774632446757,
"tag": "0007_red_nicolaos",
"breakpoints": true
},
{
"idx": 8,
"version": "7",
"when": 1775032828818,
"tag": "0008_gray_xavin",
"breakpoints": true
},
{
"idx": 9,
"version": "7",
"when": 1777370103031,
"tag": "0009_perpetual_lilandra",
"breakpoints": true
},
{
"idx": 10,
"version": "7",
"when": 1778223289077,
"tag": "0010_sudden_bastion",
"breakpoints": true
},
{
"idx": 11,
"version": "7",
"when": 1779100599148,
"tag": "0011_common_doctor_octopus",
"breakpoints": true
},
{
"idx": 12,
"version": "7",
"when": 1779118725550,
"tag": "0012_clumsy_the_stranger",
"breakpoints": true
},
{
"idx": 13,
"version": "7",
"when": 1779728850192,
"tag": "0013_naive_groot",
"breakpoints": true
},
{
"idx": 14,
"version": "7",
"when": 1780498188307,
"tag": "0014_vengeful_blonde_phantom",
"breakpoints": true
},
{
"idx": 15,
"version": "7",
"when": 1780498188308,
"tag": "0015_concerned_piledriver",
"breakpoints": true
},
{
"idx": 16,
"version": "7",
"when": 1782847276369,
"tag": "0016_tired_dagger",
"breakpoints": true
},
{
"idx": 17,
"version": "7",
"when": 1782912836523,
"tag": "0017_nappy_dagger",
"breakpoints": true
},
{
"idx": 18,
"version": "7",
"when": 1785833974268,
"tag": "0018_blushing_scarlet_witch",
"breakpoints": true
},
{
"idx": 19,
"version": "7",
"when": 1785843526589,
"tag": "0019_low_namora",
"breakpoints": true
},
{
"idx": 20,
"version": "7",
"when": 1786787455390,
"tag": "0020_smart_war_machine",
"breakpoints": true
}
]
}