import { Module, Store, schema, getUploadUrl, getFileUrl, deleteFile } from 'modelence/server';
import { ObjectId } from 'mongodb';
const dbDocuments = new Store('documents', {
schema: {
userId: schema.userId(),
filePath: schema.string(),
createdAt: schema.date(),
},
});
export default new Module('documents', {
stores: [dbDocuments],
queries: {
// Hand out a time-limited URL only for a document the caller owns.
async getUrl({ documentId }, { user }) {
if (!user) {
throw new Error('Authentication required');
}
const doc = await dbDocuments.requireOne({
_id: new ObjectId(documentId as string),
userId: new ObjectId(user.id),
});
return getFileUrl(doc.filePath);
},
},
mutations: {
// Issue an upload URL for a path scoped to the caller, then record ownership.
async requestUpload({ contentType }, { user }) {
if (!user) {
throw new Error('Authentication required');
}
const filePath = `private/users/${user.id}/${new ObjectId().toString()}`;
const upload = await getUploadUrl({
filePath,
contentType: contentType as string,
visibility: 'private',
});
await dbDocuments.insertOne({
userId: new ObjectId(user.id),
filePath,
createdAt: new Date(),
});
return upload; // { url, fields, filePath } — the client POSTs the file to `url`
},
// Only the owner can delete.
async remove({ documentId }, { user }) {
if (!user) {
throw new Error('Authentication required');
}
const doc = await dbDocuments.requireOne({
_id: new ObjectId(documentId as string),
userId: new ObjectId(user.id),
});
await deleteFile(doc.filePath);
await dbDocuments.deleteOne({ _id: doc._id });
},
},
});