Skip to content

Commit

Permalink
Merge pull request #3983 from thematters/develop
Browse files Browse the repository at this point in the history
Release: v5.0.4
  • Loading branch information
gary02 committed Jun 13, 2024
2 parents 78a25a3 + fd47716 commit d8aa70b
Show file tree
Hide file tree
Showing 40 changed files with 723 additions and 429 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
exports.up = async (knex) => {
await knex.schema.table('article', (t) => {
t.dropColumn('uuid')
t.dropColumn('title')
t.dropColumn('slug')
t.dropColumn('cover')
t.dropColumn('upstream_id')
t.dropColumn('live')
t.dropColumn('public')
t.dropColumn('content')
t.dropColumn('summary')
t.dropColumn('language')
t.dropColumn('data_hash')
t.dropColumn('media_hash')
t.dropColumn('iscn_id')
t.dropColumn('draft_id')
})

await knex.schema.table('draft', (t) => {
t.dropColumn('uuid')
t.dropColumn('summary_customized')
t.dropColumn('word_count')
t.dropColumn('language')
t.dropColumn('data_hash')
t.dropColumn('media_hash')
t.dropColumn('prev_draft_id')
t.dropColumn('iscn_id')
t.dropColumn('pin_state')
t.dropColumn('sensitive_by_admin')
})
}

exports.down = async () => {
// do nothing
}
16 changes: 16 additions & 0 deletions db/migrations/20240529145909_migrate_article_empty_title.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
exports.up = async (knex) => {
// affect prod articles with id in (243998,262321,253780,262709,262585,262308,264186,263124,263668,265021,265465,268994,266555,267068,270498,265965,268372,267582,268126,268449,269981,269510,269294,270127,271473,270296,270958,274629,272220,273592,271769,272654,273154,273360,274074,274992,275036,275411,275909,276389,276046,276463,277421,276917,277425,277473,278627,277712,277905,278236,278033,279982,279524,279071,280941,280409,280942,281768,281276,280908,283634,282596,283018,282173,282228,282374,283452,283455,284594,284154,283836,283922,285028,389948,285432,311294,349943,359939,439395,439369,439370,420681,434821,439407,439410,439408,439415,439413,439412,439371,439414,439416,439368,439372,439375,439378,439380,439382,439383,439385,439386,439387,439388,439389,439390,439391,439392,439393,465682,439396,439397,439398,439400,439401,439405,453057,63347,469642,469640,57283,2554,29952,15420,154190,39433,39482,100932,40361,115292,122903,242266,184759,184812)
await knex.raw(`
UPDATE article_version SET title='未命名'
WHERE id IN (
SELECT avn.id FROM article_version_newest avn
JOIN article a
ON avn.article_id = a.id
WHERE avn.title ~ '^[[:space:]\\u00a0\\u180e\\u2007\\u200b-\\u200f\\u202f\\u2060\\ufeff\\u3000]*$'
AND state='active'
);`)
}

exports.down = async () => {
// do nothing
}
110 changes: 110 additions & 0 deletions db/migrations/20240612155317_update_user_reader_materialized_view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
const view = `user_reader_view`
const materialized = `user_reader_materialized`

exports.up = async (knex) => {
await knex.raw(/*sql*/ `
drop view ${view} cascade;
create view ${view} as
SELECT "user".id,
"user".uuid,
"user".user_name,
"user".display_name,
"user".description,
"user".avatar,
"user".email,
"user".email_verified,
"user".mobile,
"user".password_hash,
"user".read_speed,
"user".base_gravity,
"user".curr_gravity,
"user".language,
"user".role,
"user".state,
"user".created_at,
"user".updated_at,
a.recent_donation,
r.recent_readtime,
(COALESCE(a.recent_donation, 0::bigint)+1)*COALESCE(r.recent_readtime, 0::bigint)*COALESCE(b.boost, 1::real) AS author_score
FROM "user"
LEFT JOIN ( SELECT ts.recipient_id, count(1) AS recent_donation
FROM transaction ts
JOIN article ON ts.target_id = article.id
WHERE ts.created_at >= now() - interval '1 week'
AND ts.state = 'succeeded'
AND ts.purpose = 'donation'
AND ts.currency = 'HKD'
AND ts.target_type=4
AND article.state='active'
GROUP BY ts.recipient_id) a ON a.recipient_id = "user".id
LEFT JOIN (SELECT a2.author_id, sum(read_time) AS recent_readtime
FROM article_read_count a1
JOIN article a2 ON a1.article_id = a2.id
WHERE a1.created_at >= now() - interval '1 week'
AND a1.user_id is not null
AND a2.state = 'active'
GROUP BY a2.author_id) r ON r.author_id = "user".id
LEFT JOIN ( SELECT boost,
user_id
FROM user_boost) b ON "user".id = b.user_id
where "user".state not in ('banned', 'frozen') and "user".id != 81
order by author_score desc;
create materialized view ${materialized} as
select * from ${view};
CREATE UNIQUE INDEX ${materialized}_id on public.${materialized} (id);
CREATE INDEX ${materialized}_author_score on public.${materialized} (author_score);
`)
}

exports.down = async (knex) => {
await knex.raw(/*sql*/ `
drop view ${view} cascade;
create view ${view} as
SELECT "user".id,
"user".uuid,
"user".user_name,
"user".display_name,
"user".description,
"user".avatar,
"user".email,
"user".email_verified,
"user".mobile,
"user".password_hash,
"user".read_speed,
"user".base_gravity,
"user".curr_gravity,
"user".language,
"user".role,
"user".state,
"user".created_at,
"user".updated_at,
a.recent_donation,
r.recent_readtime,
(COALESCE(a.recent_donation, 0::bigint)+1)*COALESCE(r.recent_readtime, 0::bigint)*COALESCE(b.boost, 1::real) AS author_score
FROM "user"
LEFT JOIN ( SELECT ts.recipient_id, count(1) AS recent_donation
FROM transaction ts
WHERE ts.created_at >= now() - interval '1 week' AND ts.state = 'succeeded' AND ts.purpose = 'donation' AND ts.currency = 'HKD'
GROUP BY ts.recipient_id) a ON a.recipient_id = "user".id
LEFT JOIN (SELECT a2.author_id, sum(read_time) AS recent_readtime
FROM article_read_count a1
JOIN article a2 ON a1.article_id = a2.id
WHERE a1.created_at >= now() - interval '1 week'
AND a1.user_id is not null
GROUP BY a2.author_id) r ON r.author_id = "user".id
LEFT JOIN ( SELECT boost,
user_id
FROM user_boost) b ON "user".id = b.user_id
where "user".state not in ('banned', 'frozen') and "user".id != 81
order by author_score desc;
create materialized view ${materialized} as
select * from ${view};
CREATE UNIQUE INDEX ${materialized}_id on public.${materialized} (id);
`)
}
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "matters-server",
"version": "5.0.3",
"version": "5.0.4",
"description": "Matters Server",
"author": "Matters <hi@matters.news>",
"main": "build/index.js",
Expand Down Expand Up @@ -50,7 +50,7 @@
"@keyv/redis": "^2.6.1",
"@matters/apollo-response-cache": "^2.0.0-alpha.0",
"@matters/ipns-site-generator": "^0.1.6",
"@matters/matters-editor": "^0.2.4",
"@matters/matters-editor": "^0.2.5-alpha.0",
"@matters/passport-likecoin": "^1.0.0",
"@matters/slugify": "^0.7.3",
"@sendgrid/helpers": "^7.7.0",
Expand Down
1 change: 0 additions & 1 deletion src/common/enums/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,6 @@ export const MAX_ARTICLES_PER_CONNECTION_LIMIT = 3
export const MAX_ARTICLE_CONTENT_REVISION_LENGTH = 50

export const MAX_ARTICLE_COMMENT_LENGTH = 1200
export const MAX_COMMENT_EMPTY_PARAGRAPHS = 1

export const MAX_TAGS_PER_ARTICLE_LIMIT = 3
export const TAGS_RECOMMENDED_LIMIT = 100
Expand Down
31 changes: 23 additions & 8 deletions src/connectors/__test__/articleService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,28 +139,43 @@ describe('findByAuthor', () => {
expect(articles2[0].id).toBe('1')
})
test('order by amount of appreciations', async () => {
const draftIds = await articleService.findByAuthor('1', {
const articles = await articleService.findByAuthor('1', {
orderBy: 'mostAppreciations',
})
expect(draftIds.length).toBeDefined()
expect(articles.length).toBeDefined()
})
test('order by num of comments', async () => {
const draftIds = await articleService.findByAuthor('1', {
const articles = await articleService.findByAuthor('1', {
orderBy: 'mostComments',
})
expect(draftIds.length).toBeDefined()
expect(articles.length).toBeDefined()
})
test('order by num of donations', async () => {
const draftIds = await articleService.findByAuthor('1', {
const articles = await articleService.findByAuthor('1', {
orderBy: 'mostDonations',
})
expect(draftIds.length).toBeDefined()
expect(articles.length).toBeDefined()
})
test('filter by state', async () => {
const draftIds = await articleService.findByAuthor('1', {
const articles = await articleService.findByAuthor('1', {
state: 'archived',
})
expect(draftIds.length).toBeDefined()
expect(articles.length).toBeDefined()
})
test('excludeRestricted', async () => {
const articles = await articleService.findByAuthor('1', {
excludeRestricted: true,
})
expect(articles.length).toBeDefined()

await atomService.create({
table: 'article_recommend_setting',
data: { articleId: articles[0].id, inNewest: true, inHottest: false },
})
const excluded = await articleService.findByAuthor('1', {
excludeRestricted: true,
})
expect(excluded).not.toContain(articles[0])
})
})

Expand Down
101 changes: 101 additions & 0 deletions src/connectors/__test__/commentService.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { v4 as uuidv4 } from 'uuid'
import type { Connections } from 'definitions'

import { COMMENT_STATE, COMMENT_TYPE } from 'common/enums'

import { CommentService, AtomService } from 'connectors'

import { genConnections, closeConnections } from './utils'
Expand Down Expand Up @@ -29,6 +31,39 @@ describe('find subcomments by parent comment id', () => {
const [comments, count] = await commentService.findByParent({ id: '1' })
expect(comments.length).toBeGreaterThan(0)
expect(count).toBeGreaterThan(0)

// archived/banned comments excluded
const { id: targetTypeId } = await atomService.findFirst({
table: 'entity_type',
where: { table: 'article' },
})
await atomService.create({
table: 'comment',
data: {
type: 'article',
targetId: '1',
targetTypeId,
parentCommentId: '1',
state: COMMENT_STATE.archived,
uuid: uuidv4(),
authorId: '1',
},
})
await atomService.create({
table: 'comment',
data: {
type: 'article',
targetId: '1',
targetTypeId,
parentCommentId: '1',
state: COMMENT_STATE.banned,
uuid: uuidv4(),
authorId: '1',
},
})

const [_, count2] = await commentService.findByParent({ id: '1' })
expect(count2).toBe(count)
})
})

Expand Down Expand Up @@ -199,3 +234,69 @@ describe('find comments', () => {
)
})
})

test('count comments', async () => {
const { id: targetTypeId } = await atomService.findFirst({
table: 'entity_type',
where: { table: 'article' },
})

const originalCount = await commentService.countByArticle('1')

// archived/banned comments should be filtered
await atomService.create({
table: 'comment',
data: {
type: COMMENT_TYPE.article,
targetId: '1',
targetTypeId,
parentCommentId: null,
state: COMMENT_STATE.archived,
uuid: uuidv4(),
authorId: '1',
},
})
await atomService.create({
table: 'comment',
data: {
type: COMMENT_TYPE.article,
targetId: '1',
targetTypeId,
parentCommentId: null,
state: COMMENT_STATE.banned,
uuid: uuidv4(),
authorId: '1',
},
})

const count1 = await commentService.countByArticle('1')
expect(count1).toBe(originalCount)

// active/collapsed comments should be included
await atomService.create({
table: 'comment',
data: {
type: COMMENT_TYPE.article,
targetId: '1',
targetTypeId,
parentCommentId: null,
state: COMMENT_STATE.active,
uuid: uuidv4(),
authorId: '1',
},
})
await atomService.create({
table: 'comment',
data: {
type: COMMENT_TYPE.article,
targetId: '1',
targetTypeId,
parentCommentId: null,
state: COMMENT_STATE.collapsed,
uuid: uuidv4(),
authorId: '1',
},
})
const count2 = await commentService.countByArticle('1')
expect(count2).toBe(originalCount + 2)
})
Loading

0 comments on commit d8aa70b

Please sign in to comment.