powr-sdk-api 4.7.2 → 4.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +3 -1
- package/dist/managers/activities.js +62 -0
- package/dist/managers/index.js +5 -1
- package/dist/routes/activities.js +132 -13
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -22,7 +22,8 @@ const {
|
|
|
22
22
|
initializeTools,
|
|
23
23
|
executeTasks,
|
|
24
24
|
executeTool,
|
|
25
|
-
createTask
|
|
25
|
+
createTask,
|
|
26
|
+
createActivityFeedItem
|
|
26
27
|
} = require("./managers");
|
|
27
28
|
const {
|
|
28
29
|
verifyToken
|
|
@@ -44,5 +45,6 @@ module.exports = {
|
|
|
44
45
|
executeTasks,
|
|
45
46
|
executeTool,
|
|
46
47
|
createTask,
|
|
48
|
+
createActivityFeedItem,
|
|
47
49
|
getPowrDb
|
|
48
50
|
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
getDb
|
|
5
|
+
} = require("../services/mongo");
|
|
6
|
+
const {
|
|
7
|
+
ObjectId
|
|
8
|
+
} = require("mongodb");
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Create a feed activity entry in the activities collection.
|
|
12
|
+
* Used by host apps (e.g. Spriny) in-process and by POST /activities (feed shape).
|
|
13
|
+
*
|
|
14
|
+
* @param {Object} params - action, userId, projectId?, targetType?, targetId?, metadata?, projectName?, projectSlug?
|
|
15
|
+
* @returns {Promise<{ success: boolean, id?: string, message?: string }>}
|
|
16
|
+
*/
|
|
17
|
+
async function createActivityFeedItem(params) {
|
|
18
|
+
try {
|
|
19
|
+
const {
|
|
20
|
+
action,
|
|
21
|
+
userId,
|
|
22
|
+
projectId,
|
|
23
|
+
targetType,
|
|
24
|
+
targetId,
|
|
25
|
+
metadata = {},
|
|
26
|
+
projectName,
|
|
27
|
+
projectSlug
|
|
28
|
+
} = params;
|
|
29
|
+
if (!action || !userId) {
|
|
30
|
+
return {
|
|
31
|
+
success: false,
|
|
32
|
+
message: "action and userId are required"
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const doc = {
|
|
36
|
+
action,
|
|
37
|
+
userId: new ObjectId(userId.toString()),
|
|
38
|
+
projectId: projectId ? new ObjectId(projectId.toString()) : null,
|
|
39
|
+
targetType: targetType || null,
|
|
40
|
+
targetId: targetId ? new ObjectId(targetId.toString()) : null,
|
|
41
|
+
metadata: metadata || {},
|
|
42
|
+
projectName: projectName || null,
|
|
43
|
+
projectSlug: projectSlug || null,
|
|
44
|
+
createdAt: new Date()
|
|
45
|
+
};
|
|
46
|
+
const db = await getDb();
|
|
47
|
+
const result = await db.collection("activities").insertOne(doc);
|
|
48
|
+
return {
|
|
49
|
+
success: true,
|
|
50
|
+
id: result.insertedId.toString()
|
|
51
|
+
};
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error("createActivityFeedItem error:", error);
|
|
54
|
+
return {
|
|
55
|
+
success: false,
|
|
56
|
+
message: error.message
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
module.exports = {
|
|
61
|
+
createActivityFeedItem
|
|
62
|
+
};
|
package/dist/managers/index.js
CHANGED
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
const functionsManager = require('./functions');
|
|
4
4
|
const toolsManager = require('./tools');
|
|
5
5
|
const scheduledTasksManager = require('./tasks');
|
|
6
|
+
const {
|
|
7
|
+
createActivityFeedItem
|
|
8
|
+
} = require('./activities');
|
|
6
9
|
|
|
7
10
|
// Async Functions initialization function
|
|
8
11
|
const initializeFunctions = async (options = {}) => {
|
|
@@ -33,5 +36,6 @@ module.exports = {
|
|
|
33
36
|
initializeTools,
|
|
34
37
|
executeTasks,
|
|
35
38
|
executeTool,
|
|
36
|
-
createTask
|
|
39
|
+
createTask,
|
|
40
|
+
createActivityFeedItem
|
|
37
41
|
};
|
|
@@ -5,21 +5,119 @@ const router = express.Router();
|
|
|
5
5
|
const {
|
|
6
6
|
getDb
|
|
7
7
|
} = require("../services/mongo");
|
|
8
|
+
const {
|
|
9
|
+
ObjectId
|
|
10
|
+
} = require("mongodb");
|
|
11
|
+
const {
|
|
12
|
+
createActivityFeedItem
|
|
13
|
+
} = require("../managers/activities");
|
|
8
14
|
|
|
9
|
-
|
|
15
|
+
/**
|
|
16
|
+
* GET /activities
|
|
17
|
+
* - Content-scoped (existing): ?contentId= → returns docs with projectId + contentId (shape: activity, createdAt).
|
|
18
|
+
* - Feed: ?projectId=...&from=&to=&action=&limit= → returns feed docs (action, userId, metadata, etc.) from same collection.
|
|
19
|
+
* Feed docs have "action" field; content-scoped docs have "contentId" and "activity".
|
|
20
|
+
*/
|
|
10
21
|
router.get("/", async (req, res) => {
|
|
11
22
|
try {
|
|
12
23
|
const {
|
|
13
|
-
contentId
|
|
24
|
+
contentId,
|
|
25
|
+
from,
|
|
26
|
+
to,
|
|
27
|
+
action,
|
|
28
|
+
limit
|
|
14
29
|
} = req.query;
|
|
15
|
-
const projectId = req.projectId;
|
|
16
|
-
|
|
30
|
+
const projectId = req.projectId;
|
|
31
|
+
const isFeedRequest = from !== undefined || to !== undefined || req.query.projectId && contentId === undefined;
|
|
32
|
+
if (isFeedRequest) {
|
|
33
|
+
const projectIds = [].concat(req.query.projectId || []).filter(Boolean);
|
|
34
|
+
if (projectIds.length === 0) {
|
|
35
|
+
return res.json({
|
|
36
|
+
success: true,
|
|
37
|
+
activities: []
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
const query = {
|
|
41
|
+
projectId: {
|
|
42
|
+
$in: projectIds.map(id => new ObjectId(id))
|
|
43
|
+
},
|
|
44
|
+
action: {
|
|
45
|
+
$exists: true
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
if (from || to) {
|
|
49
|
+
query.createdAt = {};
|
|
50
|
+
if (from) query.createdAt.$gte = new Date(from);
|
|
51
|
+
if (to) query.createdAt.$lte = new Date(to);
|
|
52
|
+
}
|
|
53
|
+
if (action) query.action = action;
|
|
54
|
+
const db = await getDb();
|
|
55
|
+
const activities = await db.collection("activities").find(query).sort({
|
|
56
|
+
createdAt: -1
|
|
57
|
+
}).limit(Math.min(parseInt(limit, 10) || 50, 100)).toArray();
|
|
58
|
+
const actorIds = [...new Set(activities.map(a => {
|
|
59
|
+
var _a$userId;
|
|
60
|
+
return (_a$userId = a.userId) === null || _a$userId === void 0 ? void 0 : _a$userId.toString();
|
|
61
|
+
}).filter(Boolean))];
|
|
62
|
+
let actorDetails = {};
|
|
63
|
+
if (actorIds.length > 0) {
|
|
64
|
+
const actors = await db.collection("users").find({
|
|
65
|
+
_id: {
|
|
66
|
+
$in: actorIds.map(id => new ObjectId(id))
|
|
67
|
+
}
|
|
68
|
+
}).project({
|
|
69
|
+
_id: 1,
|
|
70
|
+
fullName: 1
|
|
71
|
+
}).toArray();
|
|
72
|
+
actorDetails = actors.reduce((acc, u) => {
|
|
73
|
+
acc[u._id.toString()] = u.fullName || "Unknown";
|
|
74
|
+
return acc;
|
|
75
|
+
}, {});
|
|
76
|
+
}
|
|
77
|
+
const assigneeIds = activities.filter(a => {
|
|
78
|
+
var _a$metadata;
|
|
79
|
+
return (_a$metadata = a.metadata) === null || _a$metadata === void 0 ? void 0 : _a$metadata.assigneeId;
|
|
80
|
+
}).map(a => a.metadata.assigneeId);
|
|
81
|
+
let assigneeDetails = {};
|
|
82
|
+
if (assigneeIds.length > 0) {
|
|
83
|
+
const assignees = await db.collection("users").find({
|
|
84
|
+
_id: {
|
|
85
|
+
$in: assigneeIds.map(id => new ObjectId(id))
|
|
86
|
+
}
|
|
87
|
+
}).project({
|
|
88
|
+
_id: 1,
|
|
89
|
+
fullName: 1
|
|
90
|
+
}).toArray();
|
|
91
|
+
assigneeDetails = assignees.reduce((acc, u) => {
|
|
92
|
+
acc[u._id.toString()] = u.fullName || "Unknown";
|
|
93
|
+
return acc;
|
|
94
|
+
}, {});
|
|
95
|
+
}
|
|
96
|
+
const enriched = activities.map(a => {
|
|
97
|
+
var _a$userId2, _a$projectId, _a$userId3, _a$metadata2;
|
|
98
|
+
return {
|
|
99
|
+
...a,
|
|
100
|
+
_id: a._id.toString(),
|
|
101
|
+
userId: (_a$userId2 = a.userId) === null || _a$userId2 === void 0 ? void 0 : _a$userId2.toString(),
|
|
102
|
+
projectId: (_a$projectId = a.projectId) === null || _a$projectId === void 0 ? void 0 : _a$projectId.toString(),
|
|
103
|
+
actorName: actorDetails[(_a$userId3 = a.userId) === null || _a$userId3 === void 0 ? void 0 : _a$userId3.toString()] || "Unknown",
|
|
104
|
+
assigneeName: (_a$metadata2 = a.metadata) !== null && _a$metadata2 !== void 0 && _a$metadata2.assigneeId ? assigneeDetails[a.metadata.assigneeId] || "Unknown" : null,
|
|
105
|
+
projectName: a.projectName || null,
|
|
106
|
+
projectSlug: a.projectSlug || null
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
return res.json({
|
|
110
|
+
success: true,
|
|
111
|
+
activities: enriched
|
|
112
|
+
});
|
|
113
|
+
}
|
|
17
114
|
const query = {
|
|
18
|
-
|
|
115
|
+
activity: {
|
|
116
|
+
$exists: true
|
|
117
|
+
}
|
|
19
118
|
};
|
|
20
|
-
if (
|
|
21
|
-
|
|
22
|
-
}
|
|
119
|
+
if (projectId) query.projectId = new ObjectId(projectId);
|
|
120
|
+
if (contentId) query.contentId = contentId;
|
|
23
121
|
const db = await getDb();
|
|
24
122
|
const activities = await db.collection("activities").find(query).toArray();
|
|
25
123
|
return res.json({
|
|
@@ -35,15 +133,36 @@ router.get("/", async (req, res) => {
|
|
|
35
133
|
}
|
|
36
134
|
});
|
|
37
135
|
|
|
38
|
-
|
|
136
|
+
/**
|
|
137
|
+
* POST /activities
|
|
138
|
+
* - Feed: body has action, userId → insert feed doc into activities collection.
|
|
139
|
+
* - Content-scoped (existing): body has contentId, activity → insert content-scoped doc.
|
|
140
|
+
*/
|
|
39
141
|
router.post("/", async (req, res) => {
|
|
40
142
|
try {
|
|
143
|
+
const body = req.body;
|
|
144
|
+
const projectId = req.projectId;
|
|
145
|
+
if (body.action && body.userId) {
|
|
146
|
+
const payload = {
|
|
147
|
+
...body,
|
|
148
|
+
projectId: body.projectId || projectId
|
|
149
|
+
};
|
|
150
|
+
const result = await createActivityFeedItem(payload);
|
|
151
|
+
if (!result.success) {
|
|
152
|
+
return res.status(400).json({
|
|
153
|
+
success: false,
|
|
154
|
+
message: result.message
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
return res.status(201).json({
|
|
158
|
+
success: true,
|
|
159
|
+
id: result.id
|
|
160
|
+
});
|
|
161
|
+
}
|
|
41
162
|
const {
|
|
42
163
|
contentId,
|
|
43
164
|
activity
|
|
44
|
-
} =
|
|
45
|
-
const projectId = req.projectId; // Use middleware-injected projectId
|
|
46
|
-
|
|
165
|
+
} = body;
|
|
47
166
|
if (!contentId || !activity) {
|
|
48
167
|
return res.status(400).json({
|
|
49
168
|
success: false,
|
|
@@ -51,7 +170,7 @@ router.post("/", async (req, res) => {
|
|
|
51
170
|
});
|
|
52
171
|
}
|
|
53
172
|
const activityData = {
|
|
54
|
-
projectId,
|
|
173
|
+
projectId: projectId ? new ObjectId(projectId) : undefined,
|
|
55
174
|
contentId,
|
|
56
175
|
activity,
|
|
57
176
|
createdAt: new Date()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "powr-sdk-api",
|
|
3
|
-
"version": "4.7.
|
|
3
|
+
"version": "4.7.3",
|
|
4
4
|
"description": "Shared API core library for PowrStack projects. Zero dependencies - works with Express, Next.js API routes, and other frameworks. All features are optional and install only what you need.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|