Skip to content

Commit db79a72

Browse files
committed
feat(backend): add comments for fsentries
1 parent 0cbe013 commit db79a72

File tree

4 files changed

+205
-0
lines changed

4 files changed

+205
-0
lines changed

src/backend/src/CoreModule.js

+3
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,9 @@ const install = async ({ services, app, useapi, modapi }) => {
344344

345345
const { DriverUsagePolicyService } = require('./services/drivers/DriverUsagePolicyService');
346346
services.registerService('driver-usage-policy', DriverUsagePolicyService);
347+
348+
const { CommentService } = require('./services/CommentService');
349+
services.registerService('comment', CommentService);
347350
}
348351

349352
const install_legacy = async ({ services }) => {
+156
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
const APIError = require("../api/APIError");
2+
const FSNodeParam = require("../api/filesystem/FSNodeParam");
3+
const configurable_auth = require("../middleware/configurable_auth");
4+
const { Endpoint } = require("../util/expressutil");
5+
const BaseService = require("./BaseService");
6+
const { DB_WRITE } = require("./database/consts");
7+
8+
class CommentService extends BaseService {
9+
static MODULES = {
10+
uuidv4: require('uuid').v4,
11+
}
12+
_init () {
13+
const svc_database = this.services.get('database');
14+
this.db = svc_database.get(DB_WRITE, 'notification');
15+
}
16+
['__on_install.routes'] (_, { app }) {
17+
const r_comment = (() => {
18+
const require = this.require;
19+
const express = require('express');
20+
return express.Router()
21+
})();
22+
23+
app.use('/comment', r_comment);
24+
25+
Endpoint({
26+
route: '/comment',
27+
methods: ['POST'],
28+
mw: [configurable_auth()],
29+
handler: async (req, res) => {
30+
const comment = await this.create_comment_({ req, res });
31+
32+
if ( ! req.body.on ) {
33+
throw APIError.create('field_missing', null, { key: 'on' });
34+
}
35+
36+
const on_ = req.body.on;
37+
38+
if ( on_.startsWith('fs:') ) {
39+
const node = await (new FSNodeParam('path')).consolidate({
40+
req,
41+
getParam: () => on_.slice(3),
42+
});
43+
44+
if ( req.body.version ) {
45+
// this.attach_comment_to_fsentry_version({
46+
// node, comment, version,
47+
// });
48+
res.status(400).send('not implemented yet');
49+
return;
50+
} else {
51+
this.attach_comment_to_fsentry({
52+
node, comment,
53+
});
54+
}
55+
}
56+
57+
res.json({
58+
uid: comment.uid,
59+
});
60+
}
61+
}).attach(app);
62+
63+
Endpoint({
64+
route: '/comment/list',
65+
methods: ['POST'],
66+
mw: [configurable_auth()],
67+
handler: async (req, res) => {
68+
if ( ! req.body.on ) {
69+
throw APIError.create('field_missing', null, { key: 'on' });
70+
}
71+
72+
const on_ = req.body.on;
73+
74+
let comments;
75+
76+
if ( on_.startsWith('fs:') ) {
77+
const node = await (new FSNodeParam('path')).consolidate({
78+
req,
79+
getParam: () => on_.slice(3),
80+
});
81+
82+
if ( req.body.version ) {
83+
// this.attach_comment_to_fsentry_version({
84+
// node, comment, version,
85+
// });
86+
res.status(400).send('not implemented yet');
87+
return;
88+
} else {
89+
comments = await this.get_comments_for_fsentry({
90+
node,
91+
});
92+
}
93+
}
94+
95+
const client_safe_comments = [];
96+
for ( const comment of comments ) {
97+
client_safe_comments.push({
98+
uid: comment.uid,
99+
text: comment.text,
100+
created: comment.created_at,
101+
});
102+
}
103+
104+
res.json({
105+
comments: client_safe_comments,
106+
});
107+
}
108+
}).attach(app);
109+
110+
}
111+
112+
async create_comment_ ({ req, res }) {
113+
if ( ! req.body.text ) {
114+
throw APIError.create('field_missing', null, { key: 'text' });
115+
}
116+
117+
const text = req.body.text;
118+
119+
const uuid = this.modules.uuidv4();
120+
121+
const result = await this.db.write(
122+
'INSERT INTO `user_comments` ' +
123+
'(`uid`, `user_id`, `metadata`, `text`) ' +
124+
'VALUES (?, ?, ?, ?)',
125+
[uuid, req.user.id, '{}', text],
126+
);
127+
128+
return {
129+
id: result.insertId,
130+
uid: uuid,
131+
};
132+
}
133+
134+
async attach_comment_to_fsentry ({ node, comment }) {
135+
await this.db.write(
136+
'INSERT INTO `user_fsentry_comments` ' +
137+
'(`user_comment_id`, `fsentry_id`) ' +
138+
'VALUES (?, ?)',
139+
[comment.id, await node.get('mysql-id')],
140+
);
141+
}
142+
143+
async get_comments_for_fsentry ({ node }) {
144+
const comments = await this.db.read(
145+
'SELECT * FROM `user_comments` ' +
146+
'JOIN `user_fsentry_comments` ' +
147+
'ON `user_comments`.`id` = `user_fsentry_comments`.`user_comment_id` ' +
148+
'WHERE `fsentry_id` = ?',
149+
[await node.get('mysql-id')],
150+
);
151+
152+
return comments;
153+
}
154+
}
155+
156+
module.exports = { CommentService };

src/backend/src/services/database/SqliteDatabaseAccessService.js

+3
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ class SqliteDatabaseAccessService extends BaseDatabaseAccessService {
132132
[26, [
133133
'0029_emulator_priv.sql',
134134
]],
135+
[27, [
136+
'0030_comments.sql',
137+
]],
135138
];
136139

137140
// Database upgrade logic
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
CREATE TABLE `user_comments` (
2+
`id` INTEGER PRIMARY KEY,
3+
`uid` TEXT NOT NULL UNIQUE,
4+
`user_id` INTEGER NOT NULL,
5+
`metadata` JSON DEFAULT NULL,
6+
`text` TEXT NOT NULL,
7+
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
8+
FOREIGN KEY("user_id") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE CASCADE
9+
);
10+
11+
CREATE INDEX `idx_user_comments_uid` ON `user_comments` (`uid`);
12+
13+
CREATE TABLE `user_fsentry_comments` (
14+
`id` INTEGER PRIMARY KEY,
15+
`user_comment_id` INTEGER NOT NULL,
16+
`fsentry_id` INTEGER NOT NULL,
17+
FOREIGN KEY("user_comment_id") REFERENCES "user_comments" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
18+
FOREIGN KEY("fsentry_id") REFERENCES "fsentries" ("id") ON DELETE CASCADE ON UPDATE CASCADE
19+
);
20+
21+
CREATE TABLE `user_fsentry_version_comments` (
22+
`id` INTEGER PRIMARY KEY,
23+
`user_comment_id` INTEGER NOT NULL,
24+
`fsentry_version_id` INTEGER NOT NULL,
25+
FOREIGN KEY("user_comment_id") REFERENCES "user_comments" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
26+
FOREIGN KEY("fsentry_version_id") REFERENCES "fsentry_versions" ("id") ON DELETE CASCADE ON UPDATE CASCADE
27+
);
28+
29+
CREATE TABLE `user_group_comments` (
30+
`id` INTEGER PRIMARY KEY,
31+
`user_comment_id` INTEGER NOT NULL,
32+
`group_id` INTEGER NOT NULL,
33+
FOREIGN KEY("user_comment_id") REFERENCES "user_comments" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
34+
FOREIGN KEY("group_id") REFERENCES "group" ("id") ON DELETE CASCADE ON UPDATE CASCADE
35+
);
36+
37+
CREATE TABLE `user_user_comments` (
38+
`id` INTEGER PRIMARY KEY,
39+
`user_comment_id` INTEGER NOT NULL,
40+
`user_id` INTEGER NOT NULL,
41+
FOREIGN KEY("user_comment_id") REFERENCES "user_comments" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
42+
FOREIGN KEY("user_id") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE CASCADE
43+
);

0 commit comments

Comments
 (0)