diff --git a/adminSiteServer/adminRouter.tsx b/adminSiteServer/adminRouter.tsx index cb920859d3d..de77928ca7c 100644 --- a/adminSiteServer/adminRouter.tsx +++ b/adminSiteServer/adminRouter.tsx @@ -317,7 +317,7 @@ getPlainRouteWithROTransaction( return res.send(explorerPage) } ) - +// TODO: this transaction is only RW because somewhere inside it we fetch images getPlainRouteNonIdempotentWithRWTransaction( adminRouter, "/datapage-preview/:id", @@ -339,7 +339,7 @@ getPlainRouteNonIdempotentWithRWTransaction( ) } ) - +// TODO: this transaction is only RW because somewhere inside it we fetch images getPlainRouteNonIdempotentWithRWTransaction( adminRouter, "/grapher/:slug", diff --git a/adminSiteServer/app.tsx b/adminSiteServer/app.tsx index 8a9e5ba7a72..4cd4c119114 100644 --- a/adminSiteServer/app.tsx +++ b/adminSiteServer/app.tsx @@ -126,6 +126,7 @@ export class OwidAdminApp { // Public preview of a Gdoc document app.get("/gdocs/:id/preview", async (req, res) => { try { + // TODO: this transaction is only RW because somewhere inside it we fetch images await db.knexReadWriteTransaction(async (knex) => { const gdoc = await getAndLoadGdocById( knex, diff --git a/adminSiteServer/mockSiteRouter.tsx b/adminSiteServer/mockSiteRouter.tsx index 3e1f470839b..72003e185b8 100644 --- a/adminSiteServer/mockSiteRouter.tsx +++ b/adminSiteServer/mockSiteRouter.tsx @@ -71,6 +71,7 @@ const mockSiteRouter = Router() mockSiteRouter.use(express.urlencoded({ extended: true })) mockSiteRouter.use(express.json()) +// TODO: this transaction is only RW because somewhere inside it we fetch images getPlainRouteNonIdempotentWithRWTransaction( mockSiteRouter, "/sitemap.xml", @@ -81,6 +82,7 @@ getPlainRouteNonIdempotentWithRWTransaction( } ) +// TODO: this transaction is only RW because somewhere inside it we fetch images getPlainRouteNonIdempotentWithRWTransaction( mockSiteRouter, "/atom.xml", @@ -91,6 +93,7 @@ getPlainRouteNonIdempotentWithRWTransaction( } ) +// TODO: this transaction is only RW because somewhere inside it we fetch images getPlainRouteNonIdempotentWithRWTransaction( mockSiteRouter, "/atom-no-topic-pages.xml", @@ -191,6 +194,7 @@ mockSiteRouter.get("/collection/custom", async (_, res) => { return res.send(await renderDynamicCollectionPage()) }) +// TODO: this transaction is only RW because somewhere inside it we fetch images getPlainRouteNonIdempotentWithRWTransaction( mockSiteRouter, "/grapher/:slug", @@ -207,6 +211,7 @@ getPlainRouteNonIdempotentWithRWTransaction( } ) +// TODO: this transaction is only RW because somewhere inside it we fetch images getPlainRouteNonIdempotentWithRWTransaction( mockSiteRouter, "/", @@ -216,6 +221,7 @@ getPlainRouteNonIdempotentWithRWTransaction( } ) +// TODO: this transaction is only RW because somewhere inside it we fetch images getPlainRouteNonIdempotentWithRWTransaction( mockSiteRouter, "/donate", @@ -226,6 +232,7 @@ mockSiteRouter.get("/thank-you", async (req, res) => res.send(await renderThankYouPage()) ) +// TODO: this transaction is only RW because somewhere inside it we fetch images getPlainRouteNonIdempotentWithRWTransaction( mockSiteRouter, "/data-insights/:pageNumberOrSlug?", @@ -285,6 +292,7 @@ getPlainRouteWithROTransaction( } ) +// TODO: this transaction is only RW because somewhere inside it we fetch images getPlainRouteNonIdempotentWithRWTransaction( mockSiteRouter, "/datapage-preview/:id", @@ -325,6 +333,7 @@ mockSiteRouter.get("/search", async (req, res) => res.send(await renderSearchPage()) ) +// TODO: this transaction is only RW because somewhere inside it we fetch images getPlainRouteNonIdempotentWithRWTransaction( mockSiteRouter, "/latest", @@ -334,6 +343,7 @@ getPlainRouteNonIdempotentWithRWTransaction( } ) +// TODO: this transaction is only RW because somewhere inside it we fetch images getPlainRouteNonIdempotentWithRWTransaction( mockSiteRouter, "/latest/page/:pageno", @@ -451,6 +461,7 @@ getPlainRouteWithROTransaction( } ) +// TODO: this transaction is only RW because somewhere inside it we fetch images getPlainRouteNonIdempotentWithRWTransaction( mockSiteRouter, "/*", diff --git a/baker/DatapageHelpers.ts b/baker/DatapageHelpers.ts index eeae249e9b3..386be565230 100644 --- a/baker/DatapageHelpers.ts +++ b/baker/DatapageHelpers.ts @@ -78,6 +78,7 @@ export const getDatapageDataV2 = async ( * see https://github.com/owid/owid-grapher/issues/2121#issue-1676097164 */ export const getDatapageGdoc = async ( + // TODO: this transaction is only RW because somewhere inside it we fetch images knex: KnexReadWriteTransaction, googleDocEditLinkOrId: string, isPreviewing: boolean diff --git a/baker/DeployUtils.ts b/baker/DeployUtils.ts index 08741e98f1d..6c5aacb5a44 100644 --- a/baker/DeployUtils.ts +++ b/baker/DeployUtils.ts @@ -33,6 +33,8 @@ export const defaultCommitMessage = async (): Promise => { /** * Initiate a deploy, without any checks. Throws error on failure. */ + +// TODO: this transaction is only RW because somewhere inside it we fetch images const triggerBakeAndDeploy = async ( deployMetadata: DeployMetadata, knex: KnexReadWriteTransaction, @@ -160,6 +162,7 @@ let deploying = false * If there are no changes in the queue, a deploy won't be initiated. */ export const deployIfQueueIsNotEmpty = async ( + // TODO: this transaction is only RW because somewhere inside it we fetch images knex: KnexReadWriteTransaction ) => { if (deploying) return diff --git a/baker/GrapherBaker.tsx b/baker/GrapherBaker.tsx index 62c3eb48bd5..0b29e38753f 100644 --- a/baker/GrapherBaker.tsx +++ b/baker/GrapherBaker.tsx @@ -90,6 +90,8 @@ const renderDatapageIfApplicable = async ( * * Render a datapage if available, otherwise render a grapher page. */ + +// TODO: this transaction is only RW because somewhere inside it we fetch images export const renderDataPageOrGrapherPage = async ( grapher: GrapherInterface, knex: db.KnexReadWriteTransaction, @@ -133,6 +135,8 @@ export async function renderDataPageV2( pageGrapher?: GrapherInterface imageMetadataDictionary?: Record }, + + // TODO: this transaction is only RW because somewhere inside it we fetch images knex: db.KnexReadWriteTransaction ) { const grapherConfigForVariable = await getMergedGrapherConfigForVariable( @@ -174,7 +178,7 @@ export async function renderDataPageV2( ) const imageMetadata: OwidGdocPostInterface["imageMetadata"] = merge( {}, - // imageMetadataDictionary, + imageMetadataDictionary, ...compact(gdocs.map((gdoc) => gdoc?.imageMetadata)) ) const relatedCharts: OwidGdocPostInterface["relatedCharts"] = gdocs.flatMap( @@ -317,6 +321,8 @@ export async function renderDataPageV2( */ export const renderPreviewDataPageOrGrapherPage = async ( grapher: GrapherInterface, + + // TODO: this transaction is only RW because somewhere inside it we fetch images knex: db.KnexReadWriteTransaction ) => { const datapage = await renderDatapageIfApplicable(grapher, true, knex) @@ -453,6 +459,8 @@ export interface BakeSingleGrapherChartArguments { export const bakeSingleGrapherChart = async ( args: BakeSingleGrapherChartArguments, + + // TODO: this transaction is only RW because somewhere inside it we fetch images knex: db.KnexReadWriteTransaction ) => { const grapher: GrapherInterface = JSON.parse(args.config) @@ -475,6 +483,7 @@ export const bakeSingleGrapherChart = async ( } export const bakeAllChangedGrapherPagesVariablesPngSvgAndDeleteRemovedGraphers = + // TODO: this transaction is only RW because somewhere inside it we fetch images async (bakedSiteDir: string, knex: db.KnexReadWriteTransaction) => { const chartsToBake: { id: number; config: string; slug: string }[] = await knexRaw( diff --git a/baker/SiteBaker.tsx b/baker/SiteBaker.tsx index b68e681870c..2cd4b42a7d2 100644 --- a/baker/SiteBaker.tsx +++ b/baker/SiteBaker.tsx @@ -480,6 +480,8 @@ export class SiteBaker { } // Bake all GDoc posts, or a subset of them if slugs are provided + + // TODO: this transaction is only RW because somewhere inside it we fetch images async bakeGDocPosts(knex: db.KnexReadWriteTransaction, slugs?: string[]) { if (!this.bakeSteps.has("gdocPosts")) return const publishedGdocs = await GdocPost.getPublishedGdocPosts(knex) @@ -544,6 +546,8 @@ export class SiteBaker { } // Bake unique individual pages + + // TODO: this transaction is only RW because somewhere inside it we fetch images private async bakeSpecialPages(knex: db.KnexReadWriteTransaction) { if (!this.bakeSteps.has("specialPages")) return await this.stageWrite( @@ -700,6 +704,7 @@ export class SiteBaker { } } + // TODO: this transaction is only RW because somewhere inside it we fetch images private async bakeDataInsights(knex: db.KnexReadWriteTransaction) { if (!this.bakeSteps.has("dataInsights")) return const latestDataInsights = await db.getPublishedDataInsights(knex, 5) @@ -768,6 +773,7 @@ export class SiteBaker { } } + // TODO: this transaction is only RW because somewhere inside it we fetch images private async bakeAuthors(knex: db.KnexReadWriteTransaction) { if (!this.bakeSteps.has("authors")) return @@ -855,6 +861,8 @@ export class SiteBaker { } // Bake the blog index + + // TODO: this transaction is only RW because somewhere inside it we fetch images private async bakeBlogIndex(knex: db.KnexReadWriteTransaction) { if (!this.bakeSteps.has("blogIndex")) return const allPosts = await getBlogIndex(knex) @@ -869,6 +877,8 @@ export class SiteBaker { } // Bake the RSS feed + + // TODO: this transaction is only RW because somewhere inside it we fetch images private async bakeRSS(knex: db.KnexReadWriteTransaction) { if (!this.bakeSteps.has("rss")) return await this.stageWrite( @@ -954,6 +964,7 @@ export class SiteBaker { this.progressBar.tick({ name: "✅ baked redirects" }) } + // TODO: this transaction is only RW because somewhere inside it we fetch images async bakeWordpressPages(knex: db.KnexReadWriteTransaction) { await this.bakeRedirects(knex) await this.bakeEmbeds(knex) @@ -964,6 +975,7 @@ export class SiteBaker { await this.bakePosts(knex) } + // TODO: this transaction is only RW because somewhere inside it we fetch images private async _bakeNonWordpressPages(knex: db.KnexReadWriteTransaction) { if (this.bakeSteps.has("countries")) { await bakeCountries(this, knex) @@ -988,6 +1000,7 @@ export class SiteBaker { await this.bakeDriveImages(knex) } + // TODO: this transaction is only RW because somewhere inside it we fetch images async bakeNonWordpressPages(knex: db.KnexReadWriteTransaction) { const progressBarTotal = nonWordpressSteps .map((step) => this.bakeSteps.has(step)) @@ -1001,6 +1014,7 @@ export class SiteBaker { await this._bakeNonWordpressPages(knex) } + // TODO: this transaction is only RW because somewhere inside it we fetch images async bakeAll(knex: db.KnexReadWriteTransaction) { // Ensure caches are correctly initialized this.flushCache() diff --git a/baker/algolia/indexToAlgolia.tsx b/baker/algolia/indexToAlgolia.tsx index 876a46f1004..44a243700a3 100644 --- a/baker/algolia/indexToAlgolia.tsx +++ b/baker/algolia/indexToAlgolia.tsx @@ -194,6 +194,7 @@ function generateGdocRecords( return records } +// TODO: this transaction is only RW because somewhere inside it we fetch images // Generate records for countries, WP posts (not including posts that have been succeeded by Gdocs equivalents), and Gdocs const getPagesRecords = async (knex: db.KnexReadWriteTransaction) => { const pageviews = await getAnalyticsPageviewsByUrlObj(knex) @@ -234,6 +235,7 @@ const indexToAlgolia = async () => { } const index = client.initIndex(getIndexName(SearchIndexName.Pages)) + // TODO: this transaction is only RW because somewhere inside it we fetch images const records = await db.knexReadWriteTransaction( getPagesRecords, db.TransactionCloseMode.Close diff --git a/baker/bakeGdocPost.ts b/baker/bakeGdocPost.ts index 29056c602a3..d63c6561395 100644 --- a/baker/bakeGdocPost.ts +++ b/baker/bakeGdocPost.ts @@ -19,6 +19,7 @@ void yargs(hideBin(process.argv)) async ({ slug }) => { const baker = new SiteBaker(BAKED_SITE_DIR, BAKED_BASE_URL) + // TODO: this transaction is only RW because somewhere inside it we fetch images await db.knexReadWriteTransaction( (trx) => baker.bakeGDocPosts(trx, [slug]), db.TransactionCloseMode.Close diff --git a/baker/bakeGdocPosts.ts b/baker/bakeGdocPosts.ts index 3d75c402a82..bf332cf237b 100644 --- a/baker/bakeGdocPosts.ts +++ b/baker/bakeGdocPosts.ts @@ -24,6 +24,7 @@ void yargs(hideBin(process.argv)) async ({ slugs }) => { const baker = new SiteBaker(BAKED_SITE_DIR, BAKED_BASE_URL) + // TODO: this transaction is only RW because somewhere inside it we fetch images await db.knexReadWriteTransaction( (trx) => baker.bakeGDocPosts(trx, slugs), db.TransactionCloseMode.Close diff --git a/baker/buildLocalBake.ts b/baker/buildLocalBake.ts index 98810dbd51e..6d401a63a9b 100644 --- a/baker/buildLocalBake.ts +++ b/baker/buildLocalBake.ts @@ -17,6 +17,8 @@ const bakeDomainToFolder = async ( await fs.mkdirp(dir) const baker = new SiteBaker(dir, baseUrl, bakeSteps) console.log(`Baking site locally with baseUrl '${baseUrl}' to dir '${dir}'`) + + // TODO: this transaction is only RW because somewhere inside it we fetch images await db.knexReadWriteTransaction( (trx) => baker.bakeAll(trx), db.TransactionCloseMode.Close diff --git a/baker/runBakeGraphers.ts b/baker/runBakeGraphers.ts index eda4ada9c37..898a4a1a78d 100755 --- a/baker/runBakeGraphers.ts +++ b/baker/runBakeGraphers.ts @@ -9,6 +9,7 @@ import * as db from "../db/db.js" */ const main = async (folder: string) => { + // TODO: this transaction is only RW because somewhere inside it we fetch images return db.knexReadWriteTransaction( (trx) => bakeAllChangedGrapherPagesVariablesPngSvgAndDeleteRemovedGraphers( diff --git a/baker/siteRenderers.tsx b/baker/siteRenderers.tsx index a2e99c0b6ec..8bf37bb6128 100644 --- a/baker/siteRenderers.tsx +++ b/baker/siteRenderers.tsx @@ -189,6 +189,7 @@ export function renderDynamicCollectionPage() { return renderToHtmlPage() } +// TODO: this transaction is only RW because somewhere inside it we fetch images export const renderGdocsPageBySlug = async ( knex: KnexReadWriteTransaction, slug: string, @@ -279,6 +280,7 @@ export const renderPost = async ( ) } +// TODO: this transaction is only RW because somewhere inside it we fetch images export const renderFrontPage = async (knex: KnexReadWriteTransaction) => { const gdocHomepageId = await getHomepageId(knex) @@ -296,6 +298,7 @@ export const renderFrontPage = async (knex: KnexReadWriteTransaction) => { } } +// TODO: this transaction is only RW because somewhere inside it we fetch images export const renderDonatePage = async (knex: KnexReadWriteTransaction) => { const faqsGdoc = (await getAndLoadGdocById( knex, @@ -336,6 +339,7 @@ export const renderDataInsightsIndexPage = ( ) } +// TODO: this transaction is only RW because somewhere inside it we fetch images export const renderBlogByPageNum = async ( pageNum: number, knex: KnexReadWriteTransaction @@ -364,6 +368,7 @@ export const renderSearchPage = () => export const renderNotFoundPage = () => renderToHtmlPage() +// TODO: this transaction is only RW because somewhere inside it we fetch images export async function makeAtomFeed(knex: KnexReadWriteTransaction) { const posts = (await getBlogIndex(knex)).slice(0, 10) return makeAtomFeedFromPosts(posts) @@ -372,6 +377,8 @@ export async function makeAtomFeed(knex: KnexReadWriteTransaction) { // We don't want to include topic pages in the atom feed that is being consumed // by Mailchimp for sending the "immediate update" newsletter. Instead topic // pages announcements are sent out manually. + +// TODO: this transaction is only RW because somewhere inside it we fetch images export async function makeAtomFeedNoTopicPages(knex: KnexReadWriteTransaction) { const posts = (await getBlogIndex(knex)) .filter((post: IndexPost) => post.type !== OwidGdocType.TopicPage) diff --git a/baker/sitemap.ts b/baker/sitemap.ts index 98c770b8fe7..544727f9562 100644 --- a/baker/sitemap.ts +++ b/baker/sitemap.ts @@ -62,6 +62,7 @@ const explorerToSitemapUrl = (program: ExplorerProgram): SitemapUrl[] => { } } +// TODO: this transaction is only RW because somewhere inside it we fetch images export const makeSitemap = async ( explorerAdminServer: ExplorerAdminServer, knex: db.KnexReadWriteTransaction diff --git a/baker/startDeployQueueServer.ts b/baker/startDeployQueueServer.ts index 499910adf0c..c21935859de 100644 --- a/baker/startDeployQueueServer.ts +++ b/baker/startDeployQueueServer.ts @@ -33,6 +33,7 @@ const main = async () => { setTimeout(deployIfQueueIsNotEmpty, 10 * 1000) }) + // TODO: this transaction is only RW because somewhere inside it we fetch images await db.knexReadWriteTransaction( deployIfQueueIsNotEmpty, db.TransactionCloseMode.Close diff --git a/db/model/Gdoc/GdocAuthor.ts b/db/model/Gdoc/GdocAuthor.ts index f5cbdc5083c..2fbca80e54c 100644 --- a/db/model/Gdoc/GdocAuthor.ts +++ b/db/model/Gdoc/GdocAuthor.ts @@ -40,12 +40,14 @@ export class GdocAuthor extends GdocBase implements OwidGdocAuthorInterface { return blocks } + // TODO: this transaction is only RW because somewhere inside it we fetch images _loadSubclassAttachments = ( knex: db.KnexReadWriteTransaction ): Promise => { return this.loadLatestWorkImages(knex) } + // TODO: this transaction is only RW because somewhere inside it we fetch images loadLatestWorkImages = async ( knex: db.KnexReadWriteTransaction ): Promise => { @@ -122,6 +124,7 @@ export class GdocAuthor extends GdocBase implements OwidGdocAuthorInterface { return errors } + // TODO: this transaction is only RW because somewhere inside it we fetch images static async getPublishedAuthors( knex: db.KnexReadWriteTransaction ): Promise { diff --git a/db/model/Gdoc/GdocBase.ts b/db/model/Gdoc/GdocBase.ts index 7fa892207b1..245c4b5a461 100644 --- a/db/model/Gdoc/GdocBase.ts +++ b/db/model/Gdoc/GdocBase.ts @@ -85,6 +85,8 @@ export class GdocBase implements OwidGdocBaseInterface { gdoc: typeof this ) => Promise = async () => [] _omittableFields: string[] = [] + + // TODO: this transaction is only RW because somewhere inside it we fetch images _loadSubclassAttachments: ( knex: db.KnexReadWriteTransaction ) => Promise = async () => undefined @@ -673,6 +675,7 @@ export class GdocBase implements OwidGdocBaseInterface { this.linkedDocuments = keyBy(linkedDocuments, "id") } + // TODO: this transaction is only RW because somewhere inside it we fetch images async loadImageMetadata( knex: db.KnexReadWriteTransaction, filenames?: string[] @@ -815,6 +818,7 @@ export class GdocBase implements OwidGdocBaseInterface { ] } + // TODO: this transaction is only RW because somewhere inside it we fetch images async loadState(knex: db.KnexReadWriteTransaction): Promise { await this.loadLinkedDocuments(knex) await this.loadImageMetadata(knex) diff --git a/db/model/Gdoc/GdocDataInsight.ts b/db/model/Gdoc/GdocDataInsight.ts index 4934986148f..cb7ffb42a33 100644 --- a/db/model/Gdoc/GdocDataInsight.ts +++ b/db/model/Gdoc/GdocDataInsight.ts @@ -58,6 +58,7 @@ export class GdocDataInsight this.latestDataInsights = await db.getPublishedDataInsights(knex, 5) } + // TODO: this transaction is only RW because somewhere inside it we fetch images static async getPublishedDataInsights( knex: db.KnexReadWriteTransaction, page?: number diff --git a/db/model/Gdoc/GdocFactory.ts b/db/model/Gdoc/GdocFactory.ts index 6afafaf9503..d1c9bf82da2 100644 --- a/db/model/Gdoc/GdocFactory.ts +++ b/db/model/Gdoc/GdocFactory.ts @@ -256,6 +256,7 @@ export async function getGdocBaseObjectBySlug( return gdoc } +// TODO: this transaction is only RW because somewhere inside it we fetch images export async function getAndLoadGdocBySlug( knex: KnexReadWriteTransaction, slug: string @@ -269,6 +270,7 @@ export async function getAndLoadGdocBySlug( return loadGdocFromGdocBase(knex, base) } +// TODO: this transaction is only RW because somewhere inside it we fetch images export async function getAndLoadGdocById( knex: KnexReadWriteTransaction, id: string, @@ -282,6 +284,8 @@ export async function getAndLoadGdocById( // From an ID, get a Gdoc object with all its metadata and state loaded, in its correct subclass. // If contentSource is Gdocs, use live data from Google, otherwise use the data in the DB. + +// TODO: this transaction is only RW because somewhere inside it we fetch images export async function loadGdocFromGdocBase( knex: KnexReadWriteTransaction, base: OwidGdocBaseInterface, @@ -324,6 +328,7 @@ export async function loadGdocFromGdocBase( return gdoc } +// TODO: this transaction is only RW because somewhere inside it we fetch images export async function getAndLoadPublishedDataInsights( knex: KnexReadWriteTransaction, page?: number @@ -369,6 +374,7 @@ export async function getAndLoadPublishedDataInsights( return gdocs as GdocDataInsight[] } +// TODO: this transaction is only RW because somewhere inside it we fetch images export async function getAndLoadPublishedGdocPosts( knex: KnexReadWriteTransaction ): Promise { @@ -414,6 +420,7 @@ export async function getAndLoadPublishedGdocPosts( return gdocs as GdocPost[] } +// TODO: this transaction is only RW because somewhere inside it we fetch images export async function loadPublishedGdocAuthors( knex: KnexReadWriteTransaction ): Promise { @@ -440,6 +447,7 @@ export async function loadPublishedGdocAuthors( return gdocs as GdocAuthor[] } +// TODO: this transaction is only RW because somewhere inside it we fetch images export async function getAndLoadListedGdocPosts( knex: KnexReadWriteTransaction ): Promise { diff --git a/db/model/Gdoc/GdocPost.ts b/db/model/Gdoc/GdocPost.ts index 3ffa58b731b..b77254be481 100644 --- a/db/model/Gdoc/GdocPost.ts +++ b/db/model/Gdoc/GdocPost.ts @@ -236,6 +236,7 @@ export class GdocPost extends GdocBase implements OwidGdocPostInterface { return parseDetails(gdoc.content.details) } + // TODO: this transaction is only RW because somewhere inside it we fetch images static async getPublishedGdocPosts( knex: KnexReadWriteTransaction ): Promise { diff --git a/db/model/Post.ts b/db/model/Post.ts index 1ed5ef2ba0c..83038876fc5 100644 --- a/db/model/Post.ts +++ b/db/model/Post.ts @@ -262,6 +262,7 @@ export const getFullPost = async ( const selectHomepagePosts: FilterFnPostRestApi = (post) => post.meta?.owid_publication_context_meta_field?.homepage === true +// TODO: this transaction is only RW because somewhere inside it we fetch images export const getBlogIndex = memoize( async (knex: db.KnexReadWriteTransaction): Promise => { const gdocPosts = await getAndLoadListedGdocPosts(knex) diff --git a/devTools/markdownTest/markdown.ts b/devTools/markdownTest/markdown.ts index c5f4c541228..141ee0ebab1 100644 --- a/devTools/markdownTest/markdown.ts +++ b/devTools/markdownTest/markdown.ts @@ -15,6 +15,7 @@ import { getAndLoadGdocBySlug } from "../../db/model/Gdoc/GdocFactory.js" async function main(parsedArgs: parseArgs.ParsedArgs) { try { + // TODO: this transaction is only RW because somewhere inside it we fetch images await knexReadWriteTransaction(async (trx) => { const gdoc = await getAndLoadGdocBySlug(trx, parsedArgs._[0]) let archieMlContent: OwidEnrichedGdocBlock[] | null