2025-02-21 04:37:57 +00:00
import { Body , Controller , Delete , Get , Header , HttpCode , HttpStatus , Post , Res } from '@nestjs/common' ;
2025-11-13 08:18:43 -05:00
import { ApiTags } from '@nestjs/swagger' ;
2025-02-21 04:37:57 +00:00
import { Response } from 'express' ;
2025-11-13 08:18:43 -05:00
import { Endpoint , HistoryBuilder } from 'src/decorators' ;
2024-04-16 07:26:37 +02:00
import { AssetResponseDto } from 'src/dtos/asset-response.dto' ;
import { AuthDto } from 'src/dtos/auth.dto' ;
2025-02-21 04:37:57 +00:00
import {
AssetDeltaSyncDto ,
AssetDeltaSyncResponseDto ,
AssetFullSyncDto ,
SyncAckDeleteDto ,
SyncAckDto ,
SyncAckSetDto ,
SyncStreamDto ,
} from 'src/dtos/sync.dto' ;
2025-11-11 17:01:14 -05:00
import { ApiTag , Permission } from 'src/enum' ;
2024-04-16 07:26:37 +02:00
import { Auth , Authenticated } from 'src/middleware/auth.guard' ;
2025-02-21 04:37:57 +00:00
import { GlobalExceptionFilter } from 'src/middleware/global-exception.filter' ;
2024-04-16 07:26:37 +02:00
import { SyncService } from 'src/services/sync.service' ;
2025-11-11 17:01:14 -05:00
@ApiTags ( ApiTag . Sync )
2024-04-16 07:26:37 +02:00
@Controller ( 'sync' )
export class SyncController {
2025-02-21 04:37:57 +00:00
constructor (
private service : SyncService ,
private errorService : GlobalExceptionFilter ,
) { }
2024-04-16 07:26:37 +02:00
2024-04-29 05:24:21 +02:00
@Post ( 'full-sync' )
2024-05-09 13:58:44 -04:00
@Authenticated ( )
2025-08-08 15:56:37 -04:00
@HttpCode ( HttpStatus . OK )
2025-11-13 08:18:43 -05:00
@Endpoint ( {
2025-11-11 17:01:14 -05:00
summary : 'Get full sync for user' ,
description : 'Retrieve all assets for a full synchronization for the authenticated user.' ,
2025-11-13 08:18:43 -05:00
history : new HistoryBuilder ( ) . added ( 'v1' ) . deprecated ( 'v2' ) ,
2025-11-11 17:01:14 -05:00
} )
2024-04-29 05:24:21 +02:00
getFullSyncForUser ( @Auth ( ) auth : AuthDto , @Body ( ) dto : AssetFullSyncDto ) : Promise < AssetResponseDto [ ] > {
return this . service . getFullSync ( auth , dto ) ;
2024-04-16 07:26:37 +02:00
}
2024-04-29 05:24:21 +02:00
@Post ( 'delta-sync' )
2024-05-09 13:58:44 -04:00
@Authenticated ( )
2025-08-08 15:56:37 -04:00
@HttpCode ( HttpStatus . OK )
2025-11-13 08:18:43 -05:00
@Endpoint ( {
2025-11-11 17:01:14 -05:00
summary : 'Get delta sync for user' ,
description : 'Retrieve changed assets since the last sync for the authenticated user.' ,
2025-11-13 08:18:43 -05:00
history : new HistoryBuilder ( ) . added ( 'v1' ) . deprecated ( 'v2' ) ,
2025-11-11 17:01:14 -05:00
} )
2024-04-29 05:24:21 +02:00
getDeltaSync ( @Auth ( ) auth : AuthDto , @Body ( ) dto : AssetDeltaSyncDto ) : Promise < AssetDeltaSyncResponseDto > {
return this . service . getDeltaSync ( auth , dto ) ;
2024-04-16 07:26:37 +02:00
}
2025-02-21 04:37:57 +00:00
@Post ( 'stream' )
2025-08-08 15:56:37 -04:00
@Authenticated ( { permission : Permission.SyncStream } )
2025-02-21 04:37:57 +00:00
@Header ( 'Content-Type' , 'application/jsonlines+json' )
@HttpCode ( HttpStatus . OK )
2025-11-13 08:18:43 -05:00
@Endpoint ( {
2025-11-11 17:01:14 -05:00
summary : 'Stream sync changes' ,
description :
'Retrieve a JSON lines streamed response of changes for synchronization. This endpoint is used by the mobile app to efficiently stay up to date with changes.' ,
2025-11-13 08:18:43 -05:00
history : new HistoryBuilder ( ) . added ( 'v1' ) . beta ( 'v1' ) . stable ( 'v2' ) ,
2025-11-11 17:01:14 -05:00
} )
2025-02-21 04:37:57 +00:00
async getSyncStream ( @Auth ( ) auth : AuthDto , @Res ( ) res : Response , @Body ( ) dto : SyncStreamDto ) {
try {
await this . service . stream ( auth , res , dto ) ;
} catch ( error : Error | any ) {
res . setHeader ( 'Content-Type' , 'application/json' ) ;
this . errorService . handleError ( res , error ) ;
}
}
@Get ( 'ack' )
2025-07-25 15:25:23 -04:00
@Authenticated ( { permission : Permission.SyncCheckpointRead } )
2025-11-13 08:18:43 -05:00
@Endpoint ( {
2025-11-11 17:01:14 -05:00
summary : 'Retrieve acknowledgements' ,
description : 'Retrieve the synchronization acknowledgments for the current session.' ,
2025-11-13 08:18:43 -05:00
history : new HistoryBuilder ( ) . added ( 'v1' ) . beta ( 'v1' ) . stable ( 'v2' ) ,
2025-11-11 17:01:14 -05:00
} )
2025-02-21 04:37:57 +00:00
getSyncAck ( @Auth ( ) auth : AuthDto ) : Promise < SyncAckDto [ ] > {
return this . service . getAcks ( auth ) ;
}
@Post ( 'ack' )
2025-07-25 15:25:23 -04:00
@Authenticated ( { permission : Permission.SyncCheckpointUpdate } )
2025-08-08 15:56:37 -04:00
@HttpCode ( HttpStatus . NO_CONTENT )
2025-11-13 08:18:43 -05:00
@Endpoint ( {
2025-11-11 17:01:14 -05:00
summary : 'Acknowledge changes' ,
description :
'Send a list of synchronization acknowledgements to confirm that the latest changes have been received.' ,
2025-11-13 08:18:43 -05:00
history : new HistoryBuilder ( ) . added ( 'v1' ) . beta ( 'v1' ) . stable ( 'v2' ) ,
2025-11-11 17:01:14 -05:00
} )
2025-02-21 04:37:57 +00:00
sendSyncAck ( @Auth ( ) auth : AuthDto , @Body ( ) dto : SyncAckSetDto ) {
return this . service . setAcks ( auth , dto ) ;
}
@Delete ( 'ack' )
2025-07-25 15:25:23 -04:00
@Authenticated ( { permission : Permission.SyncCheckpointDelete } )
2025-08-08 15:56:37 -04:00
@HttpCode ( HttpStatus . NO_CONTENT )
2025-11-13 08:18:43 -05:00
@Endpoint ( {
2025-11-11 17:01:14 -05:00
summary : 'Delete acknowledgements' ,
description : 'Delete specific synchronization acknowledgments.' ,
2025-11-13 08:18:43 -05:00
history : new HistoryBuilder ( ) . added ( 'v1' ) . beta ( 'v1' ) . stable ( 'v2' ) ,
2025-11-11 17:01:14 -05:00
} )
2025-08-08 15:56:37 -04:00
deleteSyncAck ( @Auth ( ) auth : AuthDto , @Body ( ) dto : SyncAckDeleteDto ) : Promise < void > {
2025-02-21 04:37:57 +00:00
return this . service . deleteAcks ( auth , dto ) ;
}
2024-04-16 07:26:37 +02:00
}