feat: T6 wave 1 – compliance schema, permissions, lock order, backup
Backend Image / build-and-push (push) Successful in 6m39s
Frontend Image / build-and-push (push) Successful in 11m25s

- Migrations (additive): veterinary medicines with lots and movement
  ledger, treatment medicine/lot/dose links, label particulars, authority
  notices, apiary restrictions, compliance settings and acknowledgements;
  notification category COMPLIANCE, added to non-empty Telegram lists.
- Permissions veterinary-medicines:* and compliance:* with role grants.
- LOCKABLE_TABLES: Apiary locks before Colony; T6 tables appended.
- Backup exports and restores the new tables in FK order; unsealed files
  skip them and report dropped medicine links; an open TSK draft in the
  target wins.
- describeNullContracts shared helper; Telegram backlog e2e no longer
  depends on the time of day.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
Nick SzaunigandClaude Opus 5.5 committed 2026-10-15 13:04:13 +02:00
1 parent 7a1480138d
commit 8a31c42578
23 files changed
+2028 -84

No files matched your search

+19 -1
View File
@@ -357,7 +357,7 @@ describe('Notifications (e2e)', () => {
digestTime: '06:30',
quietFrom: '21:00',
quietUntil: '06:30',
telegramCategories: ['TASK_DUE', 'DIGEST'],
telegramCategories: ['TASK_DUE', 'DIGEST', 'COMPLIANCE'],
telegramDetail: true,
});
// configured / botUsername follow the environment of the process.
@@ -399,6 +399,24 @@ describe('Notifications (e2e)', () => {
expect(stored.digestTime).toBe('07:15');
});
it('accepts COMPLIANCE as a Telegram category and rejects an unknown one', async () => {
const response = await request(server())
.patch('/api/v1/profile/notification-settings')
.set(as('staff'))
.send({ telegramCategories: ['COMPLIANCE', 'DIGEST'] })
.expect(200);
expect((response.body as SettingsBody).telegramCategories).toEqual([
'COMPLIANCE',
'DIGEST',
]);
await request(server())
.patch('/api/v1/profile/notification-settings')
.set(as('staff'))
.send({ telegramCategories: ['AUTHORITY'] })
.expect(400);
});
it('rejects a digest time outside 05:00 to 12:00 and a lone quiet-hour value', async () => {
const early = await request(server())
.patch('/api/v1/profile/notification-settings')