@ExecuteOn(TaskExecutors.IO)
    @Get(uri = "/export/by-query", produces = MediaType.APPLICATION_OCTET_STREAM)
    @Operation(
        tags = {"Templates"},
        summary = "Export templates as a ZIP archive of yaml sources."
    )
    public HttpResponse<byte[]> exportByQuery(
        @Parameter(description = "A string filter") @Nullable @QueryValue(value = "q") String query,
        @Parameter(description = "A namespace filter prefix") @Nullable @QueryValue String namespace
    ) throws IOException {
        var templates = templateRepository.find(tenantService.resolveTenant(), query, namespace);
        var bytes = zipTemplates(templates);
        return HttpResponse.ok(bytes).header("Content-Disposition", "attachment; filename=\"templates.zip\"");
    }
@Test
    void exportByQuery() throws IOException {
        // create 3 templates, so we have at least 3 of them
        client.toBlocking().retrieve(POST("/api/v1/templates", createTemplate()), Template.class);
        client.toBlocking().retrieve(POST("/api/v1/templates", createTemplate()), Template.class);
        client.toBlocking().retrieve(POST("/api/v1/templates", createTemplate()), Template.class);
        int size = client.toBlocking().retrieve(HttpRequest.GET("/api/v1/templates/search?namespace=kestra.test"), Argument.of(PagedResults.class, Template.class)).getResults().size();

        byte[] zip = client.toBlocking().retrieve(HttpRequest.GET("/api/v1/templates/export/by-query?namespace=kestra.test"),
            Argument.of(byte[].class));
        File file = File.createTempFile("templates", ".zip");
        Files.write(file.toPath(), zip);

        try (ZipFile zipFile = new ZipFile(file)) {
            assertThat(zipFile.stream().count(), is((long) size));
        }

        file.delete();
    }