server: remove denormalized note visibility field
ci/woodpecker/push/lint-foundkey-js Pipeline was successful Details
ci/woodpecker/push/lint-sw Pipeline failed Details
ci/woodpecker/push/lint-client Pipeline failed Details
ci/woodpecker/push/lint-backend Pipeline failed Details
ci/woodpecker/push/build Pipeline was successful Details
ci/woodpecker/push/test Pipeline failed Details

Changelog: Fixed
This commit is contained in:
Johann150 2024-01-03 00:01:25 +01:00
parent 2cf80a8ccf
commit 78359daac6
Signed by: Johann150
GPG Key ID: 9EE6577A2A06F8F1
7 changed files with 11 additions and 94 deletions

View File

@ -0,0 +1,10 @@
export class removeNoteVisibility1704236065406 {
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "poll" DROP COLUMN "noteVisibility"`);
await queryRunner.query(`DROP TYPE "poll_notevisibility_enum"`);
}
async down(queryRunner) {
await queryRunner.query(`CREATE TYPE "poll_notevisibility_enum" AS ENUM('public', 'home', 'followers', 'specified')`);
await queryRunner.query(`ALTER TABLE "poll" ADD "noteVisibility" "poll_notevisibility_enum" NOT NULL`);
}
}

View File

@ -9,7 +9,7 @@
"watch": "node watch.mjs",
"lint": "tsc --noEmit --skipLibCheck && eslint src --ext .ts",
"mocha": "NODE_ENV=test mocha",
"migrate": "npx typeorm migration:run -d ormconfig.js",
"migrate": "yarn exec typeorm migration:run -d ormconfig.js",
"start": "node --experimental-json-modules ./built/index.js",
"start:test": "NODE_ENV=test node --experimental-json-modules ./built/index.js",
"test": "npm run mocha"

View File

@ -34,12 +34,6 @@ export class Poll {
public votes: number[];
//#region Denormalized fields
@Column('enum', {
enum: noteVisibilities,
comment: '[Denormalized]',
})
public noteVisibility: typeof noteVisibilities[number];
@Index()
@Column({
...id(),

View File

@ -220,7 +220,6 @@ import * as ep___notes_globalTimeline from './endpoints/notes/global-timeline.js
import * as ep___notes_hybridTimeline from './endpoints/notes/hybrid-timeline.js';
import * as ep___notes_localTimeline from './endpoints/notes/local-timeline.js';
import * as ep___notes_mentions from './endpoints/notes/mentions.js';
import * as ep___notes_polls_recommendation from './endpoints/notes/polls/recommendation.js';
import * as ep___notes_polls_vote from './endpoints/notes/polls/vote.js';
import * as ep___notes_reactions from './endpoints/notes/reactions.js';
import * as ep___notes_reactions_create from './endpoints/notes/reactions/create.js';
@ -515,7 +514,6 @@ const eps = [
['notes/hybrid-timeline', ep___notes_hybridTimeline],
['notes/local-timeline', ep___notes_localTimeline],
['notes/mentions', ep___notes_mentions],
['notes/polls/recommendation', ep___notes_polls_recommendation],
['notes/polls/vote', ep___notes_polls_vote],
['notes/reactions', ep___notes_reactions],
['notes/reactions/create', ep___notes_reactions_create],

View File

@ -1,83 +0,0 @@
import { Brackets, In } from 'typeorm';
import { Polls, Mutings, Notes, PollVotes } from '@/models/index.js';
import define from '@/server/api/define.js';
export const meta = {
tags: ['notes'],
requireCredential: true,
res: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'object',
optional: false, nullable: false,
ref: 'Note',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
offset: { type: 'integer', default: 0 },
},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => {
const query = Polls.createQueryBuilder('poll')
.where('poll.userHost IS NULL')
.andWhere('poll.userId != :meId', { meId: user.id })
.andWhere('poll.noteVisibility = \'public\'')
.andWhere(new Brackets(qb => { qb
.where('poll.expiresAt IS NULL')
.orWhere('poll.expiresAt > :now', { now: new Date() });
}));
//#region exclude arleady voted polls
const votedQuery = PollVotes.createQueryBuilder('vote')
.select('vote.noteId')
.where('vote.userId = :meId', { meId: user.id });
query
.andWhere(`poll.noteId NOT IN (${ votedQuery.getQuery() })`);
query.setParameters(votedQuery.getParameters());
//#endregion
//#region mute
const mutingQuery = Mutings.createQueryBuilder('muting')
.select('muting.muteeId')
.where('muting.muterId = :muterId', { muterId: user.id });
query
.andWhere(`poll.userId NOT IN (${ mutingQuery.getQuery() })`);
query.setParameters(mutingQuery.getParameters());
//#endregion
const polls = await query
.orderBy('poll.noteId', 'DESC')
.take(ps.limit)
.skip(ps.offset)
.getMany();
if (polls.length === 0) return [];
const notes = await Notes.find({
where: {
id: In(polls.map(poll => poll.noteId)),
},
order: {
createdAt: 'DESC',
},
});
return await Notes.packMany(notes, user, {
detail: true,
});
});

View File

@ -210,7 +210,6 @@ async function insertNote(user: { id: User['id']; host: User['host']; }, data: O
expiresAt: data.poll.expiresAt,
multiple: data.poll.multiple,
votes: new Array(data.poll.choices.length).fill(0),
noteVisibility: insert.visibility,
userId: user.id,
userHost: user.host,
});

View File

@ -415,7 +415,6 @@ export type Endpoints = {
'notes/hybrid-timeline': { req: { limit?: number; sinceId?: Note['id']; untilId?: Note['id']; sinceDate?: number; untilDate?: number; }; res: Note[]; };
'notes/local-timeline': { req: { limit?: number; sinceId?: Note['id']; untilId?: Note['id']; sinceDate?: number; untilDate?: number; }; res: Note[]; };
'notes/mentions': { req: { following?: boolean; limit?: number; sinceId?: Note['id']; untilId?: Note['id']; }; res: Note[]; };
'notes/polls/recommendation': { req: TODO; res: TODO; };
'notes/polls/vote': { req: { noteId: Note['id']; choice: number; }; res: null; };
'notes/reactions': { req: { noteId: Note['id']; type?: string | null; limit?: number; }; res: NoteReaction[]; };
'notes/reactions/create': { req: { noteId: Note['id']; reaction: string; }; res: null; };