fix(twins): add one-off scripts for twins-post migration data - #21
fix(twins): add one-off scripts for twins-post migration data#21AriaEdo wants to merge 7 commits into
Conversation
Reconnects orphaned topics relations, republishes posts missing relations on their published version, and grants public read access so the twins-in-the-loop site can query twins-post/topic. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
The scripts currently appear to reference uncommitted/missing content-type UIDs in this repo and include a risky full join-table delete that could cause unintended data loss.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR adds three one-off operational scripts intended to repair data inconsistencies introduced by the earlier twins-post migration and to make twins-post / topic readable by the public role for unauthenticated GraphQL consumption.
Changes:
- Add a republish script to re-sync published
twins-postversions from their drafts. - Add a topics-relinking script to reconnect
twins-post↔topicrelations usingconnect. - Add a permissions script to grant the public role read permissions for the relevant content types.
File summaries
| File | Description |
|---|---|
| scripts/republish-twins-post.js | Republishes all draft twins-post documents to fix missing relations in the published version. |
| scripts/grant-twins-public-permissions.js | Grants public-role read permissions for twins-post and topic actions. |
| scripts/fix-twins-post-topics.js | Clears/repairs broken topic relations for a fixed set of post slugs and topic slugs. |
Review details
Suppressed comments (4)
scripts/republish-twins-post.js:28
- If any step in this script throws (e.g., during republishAll), the Strapi instance is never destroyed, which can leave DB connections open and make repeated runs flaky. Wrap the work in a try/finally that always calls app.destroy(), and move process.exit handling to the main() caller.
async function main() {
const { createStrapi, compileStrapi } = require('@strapi/strapi');
const appContext = await compileStrapi();
const app = await createStrapi(appContext).load();
scripts/grant-twins-public-permissions.js:44
- If any step in this script throws (e.g., permission create), the Strapi instance is never destroyed, which can leave DB connections open. Use try/finally to always call app.destroy(), and handle process.exit from the main() caller.
async function main() {
const { createStrapi, compileStrapi } = require('@strapi/strapi');
const appContext = await compileStrapi();
const app = await createStrapi(appContext).load();
scripts/fix-twins-post-topics.js:46
- This repo does not contain the content-type UID "api::twins-post.twins-post" outside these scripts (no committed src/api entries or other UID references), so these document-service calls will fail when running a local instance built from this codebase. Either commit the missing content-type definitions or update the UID(s) here to the ones actually present in the project.
const post = await app.documents('api::twins-post.twins-post').findFirst({
filters: { slug },
status,
});
scripts/fix-twins-post-topics.js:65
- If any step in this script throws, the Strapi instance is never destroyed, which can leave DB connections open. Wrap the work in try/finally and always call app.destroy(), then exit from the main() caller.
async function main() {
const { createStrapi, compileStrapi } = require('@strapi/strapi');
const appContext = await compileStrapi();
const app = await createStrapi(appContext).load();
- Files reviewed: 3/3 changed files
- Comments generated: 4
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Edo <aria.edo@gmail.com>
Co-authored-by: AriaEdo <1716540+AriaEdo@users.noreply.github.com>
Co-authored-by: AriaEdo <1716540+AriaEdo@users.noreply.github.com>
|
|
1 similar comment
|
|
Co-authored-by: AriaEdo <1716540+AriaEdo@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
The new scripts include behaviors that can unintentionally publish unpublished drafts and can delete more relation data than intended, creating a significant risk of data exposure/loss.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (2)
Previously missed (2) — in code that hasn't changed since the last review.
scripts/grant-twins-public-permissions.js:15
- These permission action strings reference
api::twins-post.twins-postandapi::topic.topic, but there are no corresponding content-type schemas fortwins-postortopicanywhere undersrc/apiin this repo (only article/author/category/global/roadmap). If the UIDs differ (or the types aren’t actually part of this codebase), the script will silently do nothing useful or fail at runtime—please confirm the correct UIDs for the target Strapi instance and update the action strings accordingly.
scripts/republish-twins-post.js:21 - This script republishes every draft version it finds; in Strapi draft/publish this can inadvertently publish entries that were never previously published. The header comment says it should only fix entries that were already "published" but had a broken published version, so it should skip drafts that don’t have an existing published version.
- Files reviewed: 3/3 changed files
- Comments generated: 1
- Review effort level: Lite
There was a problem hiding this comment.
🔵 Needs a closer look
The republish and topics-fix scripts currently have concrete correctness/operational risks (draft-only content may be unintentionally published; and hard-coded UIDs appear to not exist in this repo), so they are not safe to run as-is.
Review details
Suppressed comments (4)
Previously missed (2) — in code that hasn't changed since the last review.
scripts/fix-twins-post-topics.js:6
- The header comment references
migrate-twins-post.js, but that script isn’t present in this repository; that makes it unclear what migration introduced the orphaned rows. Consider rewording to refer to the “original twins-post migration” (or link the actual migration script/commit) instead of a non-existent path.
This issue also appears on line 32 of the same file.
scripts/republish-twins-post.js:6
- The header comment references
migrate-twins-post.js, but that file isn’t present in this repository; this makes it harder to understand/trace the origin of the data issue when running the script later. Consider rewording to refer to the “original twins-post migration” (or link the actual migration script/commit) instead of a non-existent path.
This issue also appears on line 13 of the same file.
scripts/republish-twins-post.js:16
findMany({ status: 'draft' })will return only the first page by default and the loop will also publish drafts that currently have no published version, which can accidentally make draft-only content public. Consider (1) setting an explicit highlimit(or paginating) and (2) skipping drafts that don’t already have a published version before callingpublish.
async function republishAll(app) {
const drafts = await app.documents(CONTENT_TYPE_UID).findMany({
status: 'draft',
});
scripts/fix-twins-post-topics.js:35
- This script hard-codes
api::twins-post.twins-postandapi::topic.topic, but those content types don’t exist in this codebase (onlyarticle,author,category,global,roadmapare defined undersrc/api/*). As-is,app.db.metadata.get('api::twins-post.twins-post')/app.documents('api::topic.topic')will fail when run from this repo; consider parameterizing the UIDs (likegrant-twins-public-permissions.jsdoes) or updating them to the actual content types used here.
async function fixTopics(app) {
const topicsAttribute = app.db.metadata.get('api::twins-post.twins-post').attributes.topics;
const joinTableName = topicsAttribute?.joinTable?.name;
const postJoinColumn = topicsAttribute?.joinTable?.joinColumn?.name;
- Files reviewed: 3/3 changed files
- Comments generated: 0 new
- Review effort level: Lite
Co-authored-by: AriaEdo <1716540+AriaEdo@users.noreply.github.com>
Updated in 1d8977a to skip draft-only entries by checking for an existing published version before republishing. The content-type UID concern is already addressed on this branch by requiring explicit UIDs and validating that each one is registered before granting permissions (fba58ce). |
There was a problem hiding this comment.
🔵 Needs a closer look
fix-twins-post-topics.js can currently crash with a TypeError due to unguarded metadata access, and republish-twins-post.js has a misleading twins-post naming/comment vs hard-coded api::article.article target.
Review details
Suppressed comments (2)
Previously missed (2) — in code that hasn't changed since the last review.
scripts/fix-twins-post-topics.js:33
app.db.metadata.get('api::twins-post.twins-post')can return undefined when that content type UID isn’t registered in the current project (it isn’t present in this repo’ssrc/api). Accessing.attributesdirectly will throw a TypeError before the later join-table sanity check runs. Use optional chaining (or an explicit guard) so the script fails with the intended, actionable error message instead of crashing.
scripts/republish-twins-post.js:12- The script name and header comment refer to “twins-post”, but the actual UID is hard-coded to
api::article.article. This mismatch makes it easy to run the script against the wrong content type (or misinterpret what it will mutate). Consider making the content-type UID an explicit CLI argument (with a safe default) and adjusting the header comment accordingly.
- Files reviewed: 3/3 changed files
- Comments generated: 0 new
- Review effort level: Lite
CONTENT_TYPE_UID was left as api::article.article, a content type that doesn't exist in this project. Should target api::twins-post.twins-post, matching the migration this script repairs. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
Critical data-safety and correctness issues remain in the repair and republish scripts.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
scripts/fix-twins-post-topics.js:71
- This success message is emitted even when neither version was found: both missing-version branches only warn and continue, then line 71 still says the post was linked. That can make an incomplete migration look successful; track which versions were actually updated and report partial/failure instead of unconditionally logging success.
- Files reviewed: 3/3 changed files
- Comments generated: 3
- Review effort level: Lite
| // Clear only the orphaned link rows left by the original migration. | ||
| await app.db.connection(joinTableName).whereNull(postJoinColumn).del(); |
| const published = await app.documents(CONTENT_TYPE_UID).findFirst({ | ||
| documentId: draft.documentId, | ||
| status: 'published', | ||
| }); |
| await app.documents(CONTENT_TYPE_UID).publish({ | ||
| documentId: draft.documentId, | ||
| }); |
Summary
scripts/fix-twins-post-topics.jsto reconnect orphaned topics relations left by the original twins-post migration (bare documentId arrays weren't handled correctly by the document service)scripts/republish-twins-post.jsto republish posts whose published version is missing topics/blocks/cover relationsscripts/grant-twins-public-permissions.jsto grant the public role read access to twins-post/topic so twins-in-the-loop can query them without a tokenTest plan
🤖 Generated with Claude Code