streamby-core 0.28.6 → 0.29.0

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.
@@ -29,6 +29,8 @@ const renderFarm_1 = require("./routes/renderFarm");
29
29
  const review_1 = require("./routes/review");
30
30
  const distribution_1 = require("./routes/distribution");
31
31
  const ai_1 = require("./routes/ai");
32
+ const production_1 = require("./routes/production");
33
+ const rights_1 = require("./routes/rights");
32
34
  function createStreamByRouter(config) {
33
35
  const router = express_1.default.Router();
34
36
  if (config.encrypt)
@@ -81,5 +83,7 @@ function createStreamByRouter(config) {
81
83
  router.use((0, review_1.reviewRouter)(config));
82
84
  router.use((0, distribution_1.distributionRouter)(config));
83
85
  router.use((0, ai_1.aiRouter)(config));
86
+ router.use((0, production_1.productionRouter)(config));
87
+ router.use((0, rights_1.rightsRouter)(config));
84
88
  return router;
85
89
  }
@@ -0,0 +1,3 @@
1
+ import { Router } from 'express';
2
+ import { StreamByConfig } from '../../types';
3
+ export declare function productionRouter(_config: StreamByConfig): Router;
@@ -0,0 +1,362 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.productionRouter = productionRouter;
7
+ const express_1 = require("express");
8
+ const auth_1 = require("../../utils/auth");
9
+ const connectionManager_1 = require("../../adapters/database/connectionManager");
10
+ const manager_1 = require("../../models/manager");
11
+ const crypto_1 = __importDefault(require("crypto"));
12
+ function getDb() {
13
+ const ids = (0, connectionManager_1.getConnectedIds)().filter(id => (0, connectionManager_1.getConnection)(id).type === 'nosql');
14
+ if (!ids.length)
15
+ return null;
16
+ return (0, connectionManager_1.getConnection)(ids[0]).client.db();
17
+ }
18
+ function productionRouter(_config) {
19
+ const router = (0, express_1.Router)();
20
+ const Project = (0, manager_1.getModel)('projects');
21
+ // ── Sequences ──────────────────────────────────────────────────────────────
22
+ router.get('/projects/:projectId/production/sequences', async (req, res) => {
23
+ try {
24
+ const auth = req.auth;
25
+ const { projectId } = req.params;
26
+ const project = await Project.findOne({ _id: projectId });
27
+ if (!project)
28
+ return res.status(404).json({ message: 'Project not found' });
29
+ if (!(0, auth_1.isProjectMember)(project, auth.userId))
30
+ return res.status(403).json({ message: 'Unauthorized' });
31
+ const db = getDb();
32
+ if (!db)
33
+ return res.status(500).json({ message: 'Database not available' });
34
+ const sequences = await db.collection('production_sequences')
35
+ .find({ projectId })
36
+ .sort({ order: 1, createdAt: 1 })
37
+ .toArray();
38
+ res.json({ sequences });
39
+ }
40
+ catch (err) {
41
+ res.status(500).json({ message: err.message });
42
+ }
43
+ });
44
+ router.post('/projects/:projectId/production/sequences', async (req, res) => {
45
+ try {
46
+ const auth = req.auth;
47
+ const { projectId } = req.params;
48
+ const { name, description, order } = req.body;
49
+ if (!name)
50
+ return res.status(400).json({ message: 'name is required' });
51
+ const project = await Project.findOne({ _id: projectId });
52
+ if (!project)
53
+ return res.status(404).json({ message: 'Project not found' });
54
+ if (!(0, auth_1.isProjectMember)(project, auth.userId))
55
+ return res.status(403).json({ message: 'Unauthorized' });
56
+ const db = getDb();
57
+ if (!db)
58
+ return res.status(500).json({ message: 'Database not available' });
59
+ const now = new Date();
60
+ const sequence = {
61
+ id: crypto_1.default.randomUUID(),
62
+ projectId,
63
+ name,
64
+ description: description ?? null,
65
+ order: order ?? 0,
66
+ createdBy: auth.userId,
67
+ createdAt: now,
68
+ updatedAt: now,
69
+ };
70
+ await db.collection('production_sequences').insertOne({ ...sequence });
71
+ res.status(201).json({ sequence });
72
+ }
73
+ catch (err) {
74
+ res.status(500).json({ message: err.message });
75
+ }
76
+ });
77
+ router.patch('/projects/:projectId/production/sequences/:seqId', async (req, res) => {
78
+ try {
79
+ const auth = req.auth;
80
+ const { projectId, seqId } = req.params;
81
+ const project = await Project.findOne({ _id: projectId });
82
+ if (!project)
83
+ return res.status(404).json({ message: 'Project not found' });
84
+ if (!(0, auth_1.isProjectMember)(project, auth.userId))
85
+ return res.status(403).json({ message: 'Unauthorized' });
86
+ const db = getDb();
87
+ if (!db)
88
+ return res.status(500).json({ message: 'Database not available' });
89
+ const { name, description, order } = req.body;
90
+ const $set = { updatedAt: new Date() };
91
+ if (name !== undefined)
92
+ $set.name = name;
93
+ if (description !== undefined)
94
+ $set.description = description;
95
+ if (order !== undefined)
96
+ $set.order = order;
97
+ const result = await db.collection('production_sequences').findOneAndUpdate({ id: seqId, projectId }, { $set }, { returnDocument: 'after' });
98
+ if (!result)
99
+ return res.status(404).json({ message: 'Sequence not found' });
100
+ res.json({ sequence: result });
101
+ }
102
+ catch (err) {
103
+ res.status(500).json({ message: err.message });
104
+ }
105
+ });
106
+ router.delete('/projects/:projectId/production/sequences/:seqId', async (req, res) => {
107
+ try {
108
+ const auth = req.auth;
109
+ const { projectId, seqId } = req.params;
110
+ const project = await Project.findOne({ _id: projectId });
111
+ if (!project)
112
+ return res.status(404).json({ message: 'Project not found' });
113
+ if (!(0, auth_1.isProjectMember)(project, auth.userId))
114
+ return res.status(403).json({ message: 'Unauthorized' });
115
+ const db = getDb();
116
+ if (!db)
117
+ return res.status(500).json({ message: 'Database not available' });
118
+ await db.collection('production_sequences').deleteOne({ id: seqId, projectId });
119
+ await db.collection('production_shots').deleteMany({ sequenceId: seqId, projectId });
120
+ res.json({ message: 'Sequence deleted' });
121
+ }
122
+ catch (err) {
123
+ res.status(500).json({ message: err.message });
124
+ }
125
+ });
126
+ // ── Shots ──────────────────────────────────────────────────────────────────
127
+ router.get('/projects/:projectId/production/sequences/:seqId/shots', async (req, res) => {
128
+ try {
129
+ const auth = req.auth;
130
+ const { projectId, seqId } = req.params;
131
+ const project = await Project.findOne({ _id: projectId });
132
+ if (!project)
133
+ return res.status(404).json({ message: 'Project not found' });
134
+ if (!(0, auth_1.isProjectMember)(project, auth.userId))
135
+ return res.status(403).json({ message: 'Unauthorized' });
136
+ const db = getDb();
137
+ if (!db)
138
+ return res.status(500).json({ message: 'Database not available' });
139
+ const shots = await db.collection('production_shots')
140
+ .find({ sequenceId: seqId, projectId })
141
+ .sort({ order: 1, createdAt: 1 })
142
+ .toArray();
143
+ res.json({ shots });
144
+ }
145
+ catch (err) {
146
+ res.status(500).json({ message: err.message });
147
+ }
148
+ });
149
+ router.post('/projects/:projectId/production/sequences/:seqId/shots', async (req, res) => {
150
+ try {
151
+ const auth = req.auth;
152
+ const { projectId, seqId } = req.params;
153
+ const { name, description, status, assignedTo, assetId, exportId, dueDate, order } = req.body;
154
+ if (!name)
155
+ return res.status(400).json({ message: 'name is required' });
156
+ const project = await Project.findOne({ _id: projectId });
157
+ if (!project)
158
+ return res.status(404).json({ message: 'Project not found' });
159
+ if (!(0, auth_1.isProjectMember)(project, auth.userId))
160
+ return res.status(403).json({ message: 'Unauthorized' });
161
+ const db = getDb();
162
+ if (!db)
163
+ return res.status(500).json({ message: 'Database not available' });
164
+ const now = new Date();
165
+ const shot = {
166
+ id: crypto_1.default.randomUUID(),
167
+ sequenceId: seqId,
168
+ projectId,
169
+ name,
170
+ description: description ?? null,
171
+ order: order ?? 0,
172
+ status: status ?? 'todo',
173
+ assignedTo: assignedTo ?? [],
174
+ assetId: assetId ?? null,
175
+ exportId: exportId ?? null,
176
+ dueDate: dueDate ? new Date(dueDate) : null,
177
+ createdBy: auth.userId,
178
+ createdAt: now,
179
+ updatedAt: now,
180
+ };
181
+ await db.collection('production_shots').insertOne({ ...shot });
182
+ res.status(201).json({ shot });
183
+ }
184
+ catch (err) {
185
+ res.status(500).json({ message: err.message });
186
+ }
187
+ });
188
+ router.patch('/projects/:projectId/production/shots/:shotId', async (req, res) => {
189
+ try {
190
+ const auth = req.auth;
191
+ const { projectId, shotId } = req.params;
192
+ const project = await Project.findOne({ _id: projectId });
193
+ if (!project)
194
+ return res.status(404).json({ message: 'Project not found' });
195
+ if (!(0, auth_1.isProjectMember)(project, auth.userId))
196
+ return res.status(403).json({ message: 'Unauthorized' });
197
+ const db = getDb();
198
+ if (!db)
199
+ return res.status(500).json({ message: 'Database not available' });
200
+ const { name, description, status, assignedTo, assetId, exportId, dueDate, order } = req.body;
201
+ const $set = { updatedAt: new Date() };
202
+ if (name !== undefined)
203
+ $set.name = name;
204
+ if (description !== undefined)
205
+ $set.description = description;
206
+ if (status !== undefined)
207
+ $set.status = status;
208
+ if (assignedTo !== undefined)
209
+ $set.assignedTo = assignedTo;
210
+ if (assetId !== undefined)
211
+ $set.assetId = assetId;
212
+ if (exportId !== undefined)
213
+ $set.exportId = exportId;
214
+ if (dueDate !== undefined)
215
+ $set.dueDate = dueDate ? new Date(dueDate) : null;
216
+ if (order !== undefined)
217
+ $set.order = order;
218
+ const result = await db.collection('production_shots').findOneAndUpdate({ id: shotId, projectId }, { $set }, { returnDocument: 'after' });
219
+ if (!result)
220
+ return res.status(404).json({ message: 'Shot not found' });
221
+ res.json({ shot: result });
222
+ }
223
+ catch (err) {
224
+ res.status(500).json({ message: err.message });
225
+ }
226
+ });
227
+ router.delete('/projects/:projectId/production/shots/:shotId', async (req, res) => {
228
+ try {
229
+ const auth = req.auth;
230
+ const { projectId, shotId } = req.params;
231
+ const project = await Project.findOne({ _id: projectId });
232
+ if (!project)
233
+ return res.status(404).json({ message: 'Project not found' });
234
+ if (!(0, auth_1.isProjectMember)(project, auth.userId))
235
+ return res.status(403).json({ message: 'Unauthorized' });
236
+ const db = getDb();
237
+ if (!db)
238
+ return res.status(500).json({ message: 'Database not available' });
239
+ await db.collection('production_shots').deleteOne({ id: shotId, projectId });
240
+ await db.collection('production_tasks').deleteMany({ shotId, projectId });
241
+ res.json({ message: 'Shot deleted' });
242
+ }
243
+ catch (err) {
244
+ res.status(500).json({ message: err.message });
245
+ }
246
+ });
247
+ // ── Tasks ──────────────────────────────────────────────────────────────────
248
+ router.get('/projects/:projectId/production/shots/:shotId/tasks', async (req, res) => {
249
+ try {
250
+ const auth = req.auth;
251
+ const { projectId, shotId } = req.params;
252
+ const project = await Project.findOne({ _id: projectId });
253
+ if (!project)
254
+ return res.status(404).json({ message: 'Project not found' });
255
+ if (!(0, auth_1.isProjectMember)(project, auth.userId))
256
+ return res.status(403).json({ message: 'Unauthorized' });
257
+ const db = getDb();
258
+ if (!db)
259
+ return res.status(500).json({ message: 'Database not available' });
260
+ const tasks = await db.collection('production_tasks')
261
+ .find({ shotId, projectId })
262
+ .sort({ createdAt: 1 })
263
+ .toArray();
264
+ res.json({ tasks });
265
+ }
266
+ catch (err) {
267
+ res.status(500).json({ message: err.message });
268
+ }
269
+ });
270
+ router.post('/projects/:projectId/production/shots/:shotId/tasks', async (req, res) => {
271
+ try {
272
+ const auth = req.auth;
273
+ const { projectId, shotId } = req.params;
274
+ const { name, status, priority, assignedTo, dueDate, notes } = req.body;
275
+ if (!name)
276
+ return res.status(400).json({ message: 'name is required' });
277
+ const project = await Project.findOne({ _id: projectId });
278
+ if (!project)
279
+ return res.status(404).json({ message: 'Project not found' });
280
+ if (!(0, auth_1.isProjectMember)(project, auth.userId))
281
+ return res.status(403).json({ message: 'Unauthorized' });
282
+ const db = getDb();
283
+ if (!db)
284
+ return res.status(500).json({ message: 'Database not available' });
285
+ const now = new Date();
286
+ const task = {
287
+ id: crypto_1.default.randomUUID(),
288
+ shotId,
289
+ projectId,
290
+ name,
291
+ status: status ?? 'todo',
292
+ priority: priority ?? 'medium',
293
+ assignedTo: assignedTo ?? null,
294
+ dueDate: dueDate ? new Date(dueDate) : null,
295
+ notes: notes ?? null,
296
+ createdBy: auth.userId,
297
+ createdAt: now,
298
+ updatedAt: now,
299
+ };
300
+ await db.collection('production_tasks').insertOne({ ...task });
301
+ res.status(201).json({ task });
302
+ }
303
+ catch (err) {
304
+ res.status(500).json({ message: err.message });
305
+ }
306
+ });
307
+ router.patch('/projects/:projectId/production/shots/:shotId/tasks/:taskId', async (req, res) => {
308
+ try {
309
+ const auth = req.auth;
310
+ const { projectId, shotId, taskId } = req.params;
311
+ const project = await Project.findOne({ _id: projectId });
312
+ if (!project)
313
+ return res.status(404).json({ message: 'Project not found' });
314
+ if (!(0, auth_1.isProjectMember)(project, auth.userId))
315
+ return res.status(403).json({ message: 'Unauthorized' });
316
+ const db = getDb();
317
+ if (!db)
318
+ return res.status(500).json({ message: 'Database not available' });
319
+ const { name, status, priority, assignedTo, dueDate, notes } = req.body;
320
+ const $set = { updatedAt: new Date() };
321
+ if (name !== undefined)
322
+ $set.name = name;
323
+ if (status !== undefined)
324
+ $set.status = status;
325
+ if (priority !== undefined)
326
+ $set.priority = priority;
327
+ if (assignedTo !== undefined)
328
+ $set.assignedTo = assignedTo;
329
+ if (dueDate !== undefined)
330
+ $set.dueDate = dueDate ? new Date(dueDate) : null;
331
+ if (notes !== undefined)
332
+ $set.notes = notes;
333
+ const result = await db.collection('production_tasks').findOneAndUpdate({ id: taskId, shotId, projectId }, { $set }, { returnDocument: 'after' });
334
+ if (!result)
335
+ return res.status(404).json({ message: 'Task not found' });
336
+ res.json({ task: result });
337
+ }
338
+ catch (err) {
339
+ res.status(500).json({ message: err.message });
340
+ }
341
+ });
342
+ router.delete('/projects/:projectId/production/shots/:shotId/tasks/:taskId', async (req, res) => {
343
+ try {
344
+ const auth = req.auth;
345
+ const { projectId, shotId, taskId } = req.params;
346
+ const project = await Project.findOne({ _id: projectId });
347
+ if (!project)
348
+ return res.status(404).json({ message: 'Project not found' });
349
+ if (!(0, auth_1.isProjectMember)(project, auth.userId))
350
+ return res.status(403).json({ message: 'Unauthorized' });
351
+ const db = getDb();
352
+ if (!db)
353
+ return res.status(500).json({ message: 'Database not available' });
354
+ await db.collection('production_tasks').deleteOne({ id: taskId, shotId, projectId });
355
+ res.json({ message: 'Task deleted' });
356
+ }
357
+ catch (err) {
358
+ res.status(500).json({ message: err.message });
359
+ }
360
+ });
361
+ return router;
362
+ }
@@ -0,0 +1,3 @@
1
+ import { Router } from 'express';
2
+ import { StreamByConfig } from '../../types';
3
+ export declare function rightsRouter(_config: StreamByConfig): Router;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rightsRouter = rightsRouter;
4
+ const express_1 = require("express");
5
+ const auth_1 = require("../../utils/auth");
6
+ const connectionManager_1 = require("../../adapters/database/connectionManager");
7
+ const manager_1 = require("../../models/manager");
8
+ function getDb() {
9
+ const ids = (0, connectionManager_1.getConnectedIds)().filter(id => (0, connectionManager_1.getConnection)(id).type === 'nosql');
10
+ if (!ids.length)
11
+ return null;
12
+ return (0, connectionManager_1.getConnection)(ids[0]).client.db();
13
+ }
14
+ function rightsRouter(_config) {
15
+ const router = (0, express_1.Router)();
16
+ const Project = (0, manager_1.getModel)('projects');
17
+ // GET /projects/:projectId/assets/:assetId/rights
18
+ router.get('/projects/:projectId/assets/:assetId/rights', async (req, res) => {
19
+ try {
20
+ const auth = req.auth;
21
+ const { projectId, assetId } = req.params;
22
+ const project = await Project.findOne({ _id: projectId });
23
+ if (!project)
24
+ return res.status(404).json({ message: 'Project not found' });
25
+ if (!(0, auth_1.isProjectMember)(project, auth.userId))
26
+ return res.status(403).json({ message: 'Unauthorized' });
27
+ const db = getDb();
28
+ if (!db)
29
+ return res.status(500).json({ message: 'Database not available' });
30
+ const rights = await db.collection('asset_rights').findOne({ assetId, projectId });
31
+ res.json({ rights: rights ?? null });
32
+ }
33
+ catch (err) {
34
+ res.status(500).json({ message: err.message });
35
+ }
36
+ });
37
+ // PUT /projects/:projectId/assets/:assetId/rights (upsert)
38
+ router.put('/projects/:projectId/assets/:assetId/rights', async (req, res) => {
39
+ try {
40
+ const auth = req.auth;
41
+ const { projectId, assetId } = req.params;
42
+ const project = await Project.findOne({ _id: projectId });
43
+ if (!project)
44
+ return res.status(404).json({ message: 'Project not found' });
45
+ if (!(0, auth_1.isProjectMember)(project, auth.userId))
46
+ return res.status(403).json({ message: 'Unauthorized' });
47
+ const db = getDb();
48
+ if (!db)
49
+ return res.status(500).json({ message: 'Database not available' });
50
+ const { rightsHolder, licenseType, licenseUrl, territory, expiresAt, usageRestrictions, notes } = req.body;
51
+ const now = new Date();
52
+ const payload = {
53
+ assetId,
54
+ projectId,
55
+ licenseType: licenseType ?? 'unknown',
56
+ updatedBy: auth.userId,
57
+ updatedAt: now,
58
+ };
59
+ if (rightsHolder !== undefined)
60
+ payload.rightsHolder = rightsHolder;
61
+ if (licenseUrl !== undefined)
62
+ payload.licenseUrl = licenseUrl;
63
+ if (territory !== undefined)
64
+ payload.territory = territory;
65
+ if (expiresAt !== undefined)
66
+ payload.expiresAt = expiresAt ? new Date(expiresAt) : null;
67
+ if (usageRestrictions !== undefined)
68
+ payload.usageRestrictions = usageRestrictions;
69
+ if (notes !== undefined)
70
+ payload.notes = notes;
71
+ await db.collection('asset_rights').updateOne({ assetId, projectId }, { $set: payload }, { upsert: true });
72
+ const rights = await db.collection('asset_rights').findOne({ assetId, projectId });
73
+ res.json({ rights });
74
+ }
75
+ catch (err) {
76
+ res.status(500).json({ message: err.message });
77
+ }
78
+ });
79
+ return router;
80
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "streamby-core",
3
- "version": "0.28.6",
3
+ "version": "0.29.0",
4
4
  "description": "StreamBy middleware framework for media storage management",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",