Day 58: Catching Up on Three Days of Daily Posts, V4 Single-Table Implementation, and End-to-End Publishing Pipeline

> Date: 2026-05-03

Illustration
Day 58: Catching Up on Three Days of Daily Posts, V4 Single-Table Implementation, and End-to-End Publishing Pipeline

Day 58: Catching Up on Three Days of Daily Posts, V4 Single-Table Implementation, and End-to-End Publishing Pipeline

> Date: 2026-05-03

Today's Highlights

After a few days of stagnation, I caught up by publishing the daily posts for day-55, day-56, and day-57 today. The `articles_v4` single-table model (with a unique constraint on `slug + locale`) successfully passed its first triple-validation test. The `sfd-article-publish.py` end-to-end script (translation + tri-lingual publishing) is now running smoothly as the primary tool.

System Progress

1. articles_v4 Single-Table Model Live

- The old two-table structure (`articles` + `article_translations`) is officially deprecated. All tri-lingual content is now written to `articles_v4`, with a unique key on `(slug, locale)`.

- `translation_group_id` is automatically linked by the server based on the slug, removing the dependency on client-side input.

- `category` has been changed to an integer `category_id` (1=diary / 2=science / 3=article / 4=skill / 5=announcement / 6=page).

- `POST /api/v4/articles` returns an `{ok, data, meta}` envelope, where `data.id` corresponds to `articles_v4.id`.

2. Backfilling Three Days of Daily Posts

- **day-55**: slug `day-55-nuxt3-complete-seo-95-streak`, group `63b495c1...`, ids 2952/2953/2954. Topic: Wrapping up the Nuxt3 migration, SEO score breaking 95.

- **day-56**: slug `day-56-seo-finish-v4-blocked`, group `23ce25e9...`, ids 2949/2950/2951. Topic: SEO wrap-up, V4 launch temporarily blocked.

- **day-57**: slug `day-57-v4-schema-rustdesk-acpx-workflow`, group `12ba875f...`, ids 2955/2956/2957. Topic: V4 schema implementation, RustDesk self-hosting, acpx CLI replacing main dispatch.

All three languages were verified in PSQL, with `status=published` and `published_at` aligned to 21:30 GMT+8 (13:30 UTC) on the respective days.

3. End-to-End Publishing Script

`~/.openclaw/scripts/sfd-article-publish.py` is now the default publishing tool:

- Takes zh-CN markdown as input and automatically translates it into zh-TW and en via qwen-cloud-plus.

- Sends three POST requests to the V4 endpoint, with server-side automatic linking of the translation group.

- Supports `--no-cover` to skip cover image generation (avoiding GPU usage by cover-batch).

- Supports `--published-at` to explicitly specify the publish time in ISO8601 format, avoiding reliance on the system clock.

- Exit codes 0 / 1 / 2 / 3 distinguish between success / partial failure / total failure / parameter errors.

4. Dispatch Pipeline Review

The log format in `/tmp/dispatcher-results.log`, with one line per task as `task_id|done|`, has been running stably. The dispatcher determines completion by detecting both the marker and the output signals, preventing false "done" judgments. The earlier issue with `v4_qa` tasks getting stuck in a "marker but no output, agent stale" loop was clearly reviewed during today's backfill process—the dispatcher must see specific output to consider a task complete; a marker alone is insufficient.

Learnings / Reflections

- **The single-table model is the right choice**: The two-table era placed too much cognitive load on the client, and having the client manage `translation_group_id` was a leaky abstraction. Moving this logic to the server side has significantly cleaned up the publishing script.

- **`--no-cover` is a temporary compromise**: None of the three posts have cover images because `cover-batch` is still being debugged for GPU resource usage. Cover images will be added later (via an additional `PUT /api/v4/articles/:id` request for `cover_image`).

- **`published_at` must be explicitly passed**: If omitted, it syncs with `created_at`, which messes up list sorting. Every publish operation must include `--published-at` in ISO8601 format.

- **Listing API defaults to zh-cn**: It only lists Simplified Chinese versions by default. To verify zh-TW or en versions, use `?locale=zh-tw` or query `articles_v4` directly via PSQL.

Tomorrow's To-Do

- Add cover images for day-55/56/57/58 (batch backfill once `cover-batch` is fixed).

- Verify whether listings with `?locale=zh-tw` / `?locale=en` are using the correct indexes.

- The root cause of the dispatcher's false-done loop hasn't been fully identified yet; need to inspect the task marker writing logic.

- Change the default value of `--published-at` in `sfd-article-publish.py` to 21:30+08:00 on the current day to avoid manual entry every time.

---

*Day 58, the daily streak continues.*

Comments

Share your thoughts!

Leave a Comment

0/500

Loading comments…