Chart resyncing (#5372)
* wip * Add test * Fix test * Insert moderation log * Add todo
This commit is contained in:
		
							
								
								
									
										21
									
								
								src/server/api/endpoints/admin/resync-chart.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/server/api/endpoints/admin/resync-chart.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
import define from '../../define';
 | 
			
		||||
import { driveChart, notesChart, usersChart, instanceChart } from '../../../../services/chart';
 | 
			
		||||
import { insertModerationLog } from '../../../../services/insert-moderation-log';
 | 
			
		||||
 | 
			
		||||
export const meta = {
 | 
			
		||||
	tags: ['admin'],
 | 
			
		||||
 | 
			
		||||
	requireCredential: true,
 | 
			
		||||
	requireModerator: true,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default define(meta, async (ps, me) => {
 | 
			
		||||
	insertModerationLog(me, 'chartResync');
 | 
			
		||||
 | 
			
		||||
	driveChart.resync();
 | 
			
		||||
	notesChart.resync();
 | 
			
		||||
	usersChart.resync();
 | 
			
		||||
	instanceChart.resync();
 | 
			
		||||
 | 
			
		||||
	// TODO: ユーザーごとのチャートもキューに入れて更新する
 | 
			
		||||
});
 | 
			
		||||
@@ -6,7 +6,7 @@ import { name, schema } from '../schemas/test';
 | 
			
		||||
type TestLog = SchemaType<typeof schema>;
 | 
			
		||||
 | 
			
		||||
export default class TestChart extends Chart<TestLog> {
 | 
			
		||||
	private total = 0;
 | 
			
		||||
	public total = 0; // publicにするのはテストのため
 | 
			
		||||
 | 
			
		||||
	constructor() {
 | 
			
		||||
		super(name, schema);
 | 
			
		||||
 
 | 
			
		||||
@@ -65,7 +65,7 @@ export default abstract class Chart<T extends Record<string, any>> {
 | 
			
		||||
	public schema: Schema;
 | 
			
		||||
	protected repository: Repository<Log>;
 | 
			
		||||
	protected abstract genNewLog(latest: T): DeepPartial<T>;
 | 
			
		||||
	protected abstract async fetchActual(group?: string): Promise<DeepPartial<T>>;
 | 
			
		||||
	protected abstract async fetchActual(group: string | null): Promise<DeepPartial<T>>;
 | 
			
		||||
 | 
			
		||||
	@autobind
 | 
			
		||||
	private static convertSchemaToFlatColumnDefinitions(schema: Schema) {
 | 
			
		||||
@@ -341,6 +341,24 @@ export default abstract class Chart<T extends Record<string, any>> {
 | 
			
		||||
		]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@autobind
 | 
			
		||||
	public async resync(group: string | null = null): Promise<any> {
 | 
			
		||||
		const data = await this.fetchActual(group);
 | 
			
		||||
 | 
			
		||||
		const update = async (log: Log) => {
 | 
			
		||||
			await this.repository.createQueryBuilder()
 | 
			
		||||
				.update()
 | 
			
		||||
				.set(Chart.convertObjectToFlattenColumns(data))
 | 
			
		||||
				.where('id = :id', { id: log.id })
 | 
			
		||||
				.execute();
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		return Promise.all([
 | 
			
		||||
			this.getCurrentLog('day', group).then(log => update(log)),
 | 
			
		||||
			this.getCurrentLog('hour', group).then(log => update(log)),
 | 
			
		||||
		]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@autobind
 | 
			
		||||
	protected async inc(inc: DeepPartial<T>, group: string | null = null): Promise<void> {
 | 
			
		||||
		await this.commit(Chart.convertQuery(inc as any), group);
 | 
			
		||||
 
 | 
			
		||||
@@ -320,4 +320,60 @@ describe('Chart', () => {
 | 
			
		||||
			});
 | 
			
		||||
		}));
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	describe('Resync', () => {
 | 
			
		||||
		it('Can resync', async(async () => {
 | 
			
		||||
			testChart.total = 1;
 | 
			
		||||
 | 
			
		||||
			await testChart.resync();
 | 
			
		||||
 | 
			
		||||
			const chartHours = await testChart.getChart('hour', 3);
 | 
			
		||||
			const chartDays = await testChart.getChart('day', 3);
 | 
			
		||||
 | 
			
		||||
			assert.deepStrictEqual(chartHours, {
 | 
			
		||||
				foo: {
 | 
			
		||||
					dec: [0, 0, 0],
 | 
			
		||||
					inc: [0, 0, 0],
 | 
			
		||||
					total: [1, 0, 0]
 | 
			
		||||
				},
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			assert.deepStrictEqual(chartDays, {
 | 
			
		||||
				foo: {
 | 
			
		||||
					dec: [0, 0, 0],
 | 
			
		||||
					inc: [0, 0, 0],
 | 
			
		||||
					total: [1, 0, 0]
 | 
			
		||||
				},
 | 
			
		||||
			});
 | 
			
		||||
		}));
 | 
			
		||||
 | 
			
		||||
		it('Can resync (2)', async(async () => {
 | 
			
		||||
			await testChart.increment();
 | 
			
		||||
 | 
			
		||||
			clock.tick('01:00:00');
 | 
			
		||||
 | 
			
		||||
			testChart.total = 100;
 | 
			
		||||
 | 
			
		||||
			await testChart.resync();
 | 
			
		||||
 | 
			
		||||
			const chartHours = await testChart.getChart('hour', 3);
 | 
			
		||||
			const chartDays = await testChart.getChart('day', 3);
 | 
			
		||||
 | 
			
		||||
			assert.deepStrictEqual(chartHours, {
 | 
			
		||||
				foo: {
 | 
			
		||||
					dec: [0, 0, 0],
 | 
			
		||||
					inc: [0, 1, 0],
 | 
			
		||||
					total: [100, 1, 0]
 | 
			
		||||
				},
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			assert.deepStrictEqual(chartDays, {
 | 
			
		||||
				foo: {
 | 
			
		||||
					dec: [0, 0, 0],
 | 
			
		||||
					inc: [1, 0, 0],
 | 
			
		||||
					total: [100, 0, 0]
 | 
			
		||||
				},
 | 
			
		||||
			});
 | 
			
		||||
		}));
 | 
			
		||||
	});
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user