WIP - add and remove shares
This commit is contained in:
@@ -9,7 +9,7 @@ export interface RecordShareAccessLevel {
|
|||||||
export class RecordShare extends BaseModel {
|
export class RecordShare extends BaseModel {
|
||||||
static tableName = 'record_shares';
|
static tableName = 'record_shares';
|
||||||
|
|
||||||
// Disable automatic snake_case conversion for this table
|
// Don't use snake_case mapping since DB columns are already camelCase
|
||||||
static get columnNameMappers() {
|
static get columnNameMappers() {
|
||||||
return {
|
return {
|
||||||
parse(obj: any) {
|
parse(obj: any) {
|
||||||
@@ -21,6 +21,15 @@ export class RecordShare extends BaseModel {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Override BaseModel hooks to prevent automatic timestamp handling
|
||||||
|
$beforeInsert(queryContext: any) {
|
||||||
|
// Don't set timestamps - let database defaults handle it
|
||||||
|
}
|
||||||
|
|
||||||
|
$beforeUpdate(opt: any, queryContext: any) {
|
||||||
|
// Don't set timestamps - let database defaults handle it
|
||||||
|
}
|
||||||
|
|
||||||
id!: string;
|
id!: string;
|
||||||
objectDefinitionId!: string;
|
objectDefinitionId!: string;
|
||||||
recordId!: string;
|
recordId!: string;
|
||||||
@@ -30,6 +39,7 @@ export class RecordShare extends BaseModel {
|
|||||||
expiresAt?: Date;
|
expiresAt?: Date;
|
||||||
revokedAt?: Date;
|
revokedAt?: Date;
|
||||||
createdAt!: Date;
|
createdAt!: Date;
|
||||||
|
updatedAt!: Date;
|
||||||
|
|
||||||
static get jsonSchema() {
|
static get jsonSchema() {
|
||||||
return {
|
return {
|
||||||
@@ -49,8 +59,22 @@ export class RecordShare extends BaseModel {
|
|||||||
canDelete: { type: 'boolean' },
|
canDelete: { type: 'boolean' },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expiresAt: { type: ['string', 'null'], format: 'date-time' },
|
expiresAt: {
|
||||||
revokedAt: { type: ['string', 'null'], format: 'date-time' },
|
anyOf: [
|
||||||
|
{ type: 'string', format: 'date-time' },
|
||||||
|
{ type: 'null' },
|
||||||
|
{ type: 'object' } // Allow Date objects
|
||||||
|
]
|
||||||
|
},
|
||||||
|
revokedAt: {
|
||||||
|
anyOf: [
|
||||||
|
{ type: 'string', format: 'date-time' },
|
||||||
|
{ type: 'null' },
|
||||||
|
{ type: 'object' } // Allow Date objects
|
||||||
|
]
|
||||||
|
},
|
||||||
|
createdAt: { type: ['string', 'object'], format: 'date-time' },
|
||||||
|
updatedAt: { type: ['string', 'object'], format: 'date-time' },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,14 +147,16 @@ export class RecordSharingController {
|
|||||||
|
|
||||||
if (existingShare) {
|
if (existingShare) {
|
||||||
// Update existing share
|
// Update existing share
|
||||||
await RecordShare.query(knex)
|
await knex('record_shares')
|
||||||
.patchAndFetchById(existingShare.id, {
|
.where({ id: existingShare.id })
|
||||||
accessLevel: {
|
.update({
|
||||||
|
accessLevel: JSON.stringify({
|
||||||
canRead: data.canRead,
|
canRead: data.canRead,
|
||||||
canEdit: data.canEdit,
|
canEdit: data.canEdit,
|
||||||
canDelete: data.canDelete,
|
canDelete: data.canDelete,
|
||||||
},
|
}),
|
||||||
expiresAt: data.expiresAt ? new Date(data.expiresAt) : null,
|
expiresAt: data.expiresAt ? data.expiresAt : null,
|
||||||
|
updatedAt: knex.fn.now(),
|
||||||
});
|
});
|
||||||
|
|
||||||
return RecordShare.query(knex)
|
return RecordShare.query(knex)
|
||||||
@@ -163,21 +165,21 @@ export class RecordSharingController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create new share
|
// Create new share
|
||||||
const share = await RecordShare.query(knex).insert({
|
const [shareId] = await knex('record_shares').insert({
|
||||||
objectDefinitionId: objectDef.id,
|
objectDefinitionId: objectDef.id,
|
||||||
recordId,
|
recordId,
|
||||||
granteeUserId: data.granteeUserId,
|
granteeUserId: data.granteeUserId,
|
||||||
grantedByUserId: currentUser.userId,
|
grantedByUserId: currentUser.userId,
|
||||||
accessLevel: {
|
accessLevel: JSON.stringify({
|
||||||
canRead: data.canRead,
|
canRead: data.canRead,
|
||||||
canEdit: data.canEdit,
|
canEdit: data.canEdit,
|
||||||
canDelete: data.canDelete,
|
canDelete: data.canDelete,
|
||||||
},
|
}),
|
||||||
expiresAt: data.expiresAt ? new Date(data.expiresAt) : null,
|
expiresAt: data.expiresAt ? data.expiresAt : null,
|
||||||
});
|
});
|
||||||
|
|
||||||
return RecordShare.query(knex)
|
return RecordShare.query(knex)
|
||||||
.findById(share.id)
|
.findById(shareId)
|
||||||
.withGraphFetched('[granteeUser]');
|
.withGraphFetched('[granteeUser]');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,9 +235,11 @@ export class RecordSharingController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Revoke the share (soft delete)
|
// Revoke the share (soft delete)
|
||||||
await RecordShare.query(knex)
|
await knex('record_shares')
|
||||||
.patchAndFetchById(shareId, {
|
.where({ id: shareId })
|
||||||
revokedAt: new Date(),
|
.update({
|
||||||
|
revokedAt: knex.fn.now(),
|
||||||
|
updatedAt: knex.fn.now(),
|
||||||
});
|
});
|
||||||
|
|
||||||
return { success: true };
|
return { success: true };
|
||||||
|
|||||||
Reference in New Issue
Block a user