For Claude
Current state, 26/09/2026 (read first).- Cadence halved on every EO planner, AL 26/09/2026 (translated: "we must halve the number of EO posts per day, on every planner"), for every new scheduling, posts already scheduled kept as they are; the planner pages carry the new values. The tracker shows the rows as they are in D1 and has no cadence of its own.
- Every date on this page reads Vietnam time (Asia/Ho_Chi_Minh, +07:00): the day of a cell and the week window are Vietnam days; since 22/09/2026 nothing stays on Paris time, Pinterest included (AL).
- This load: window not loaded
- The tracker shows D1 as the hourly sync writes it, it reads neither PostFast nor Kit. Known gaps on 25/09/2026: the 69 V16 short rows are all still in D1 (40 posted, 29 scheduled) although 19 duplicates were pulled and 50 remain; NL2 of 20/09/2026 reads posted while its Kit broadcast is a draft, and the newsletter is paused (process OUT until further notice, AL 25/09/2026).
Rules and reference: codes, endpoints, import.- One row per content code type, one column per day, one week of seven days starting at the
from URL parameter (default: Monday of the current Vietnam week; the arrows move it by seven days and rewrite from, other parameters are kept). A cell holds the codes of that day (S-TT12, TT4, P31). Colour is the status written in the tracker: posted, scheduled, planned, backup. Read from D1 content_posts through /api/content-posts, written by the stream agents and, since 17/09/2026, pulled every hour from the Notion planner bases by eo-backup-worker content-posts-sync (CRON20 on /crons); the import script stays as a fallback. 19 code types. A chip with a URL opens it. Hover a chip for date, platform, status, PostFast id and source video. - Codes: n is the running number inside a code type, taken after the largest n already present in the planner of that type. Source file: content-codes.json (decision AL 12/09/2026; page built 2026-09-12, sprint 2026-09-12, section 7 of the brief).
- Source: D1 table
content_posts (migrations 0055 and 0056), one row per code AND platform (UNIQUE(code, platform)): LS1 on Instagram and LS1 on Facebook are two rows, each with its own PostFast post id; a chip then carries a platform tag (LS1 IG, LS1 FB). Columns: code_type, n, code, date, platform, planner_row_id, postfast_post_id, status, url, video, created_at. - Endpoints:
GET /api/content-posts?date_from=YYYY-MM-DD&date_to=YYYY-MM-DD&code_type=S-TT&platform=TikTok&video=V14 lists rows; POST /api/content-posts upserts one object or an array by (code, platform); a row without platform updates every row of that code when some exist (null fields never erase a stored value); ?dry=1 validates without writing. Both accept a browser session (ADMIN_EMAIL) or a CF Access service token (CF-Access-Client-Id / CF-Access-Client-Secret); the /api/admin middleware refuses service tokens, so this route lives outside it and gates itself in functions/api/content-posts.js. - Import (fallback since 17/09/2026, the hourly sync is the normal path):
node scripts/content-posts-import.mjs pushes every .jsonl of the sprint folder 3:Others/sprint-2026-09-12/tracker-rows (one JSON object per line, at least code); --dry validates only. Day of a cell = the first ten characters of date, so agents write the Vietnam date (ISO with +07:00, AL 20/09/2026). The window starts on the Monday of the current Vietnam week and can be moved week by week; the URL keeps it as ?from=YYYY-MM-DD. - Status classes: posted, published, done, live map to posted; scheduled to scheduled; backup, invalid, failed, cancelled to backup (the backup class is kept on purpose: Backup was retired as a planner status on 18/09/2026, but 155 legacy rows still carry the value and dropping the class would blank them here; nothing new is filed into it and backup planners are never synced); anything else (planned, in progress, ready, not started, empty) to planned. Since 17/09/2026 a line whose Notion page was deleted carries status
deleted with a deleted_at stamp and is not shown at all (the API hides it unless ?include_deleted=1); nothing is removed from D1. - This page, one screen since 18/09/2026 (AL: no vertical scroll at 1512x982 and 1440x900, browser at 100 %): desktop body zoom starts at 1.0 (was 1.25 from intranet.css), fitHeight() steps it down by 0.025 to 0.75 at most while the page scrolls, then the table alone scrolls inside the page (.scroller.clamp); the page never scrolls, never sideways; filters on one line, compact rows and type. Mobile unchanged.
- Cadences on every planner page set by AL 17/09/2026, then halved by AL on 26/09/2026 for every new scheduling, posts already scheduled kept as they are (Newsletter out, Substack on hold and Lifestyle at one post every 2 weeks were left as they stood); every former "slot to set" band has a one hour window since 17/09/2026.
- 18/09/2026, Backup retired as a status (AL). There must be no Backup in any planner. No planner carries a Backup option and no planner gains one, so the proposal to add the option to Substack, Newsletter, Carousels, Quotes and Lifestyle is answered no. A spare leaves the working planner for a BACKUP PLANNER of its own format; those planners are built next and nothing is moved before they exist. Measured the same day and left untouched: 155 rows still sit in Status Backup (Shorts 84, Threads 27, X 21, Pinterest 20, Carousels 2, LinkedIn 1), 145 real spares and 10 dead Shorts rows. No Status was changed by this pass.
- Notion holds the rows. eo-backup-worker content-posts-sync copies the 11 Notion planner bases into D1 content_posts every hour (cron 15 * * * *, Run now on /crons). The publication tracker and the "This week in Notion" table under each planner grid read D1 through /api/content-posts; the browser never calls Notion. A Notion row without a Code is not copied, so it shows nowhere here.
- Long teasers (61 to 90 s) go only to Instagram and Threads.
- Short types are chosen by the Shorts creation runbook and stored in the Notion Shorts planner, select property Short type (added 17/09/2026); the Shorts page shows only how many shorts, on which days, in which bands.
- LinkedIn is posted from the Elite Outsiders page since 17/09/2026 (before: the Alexandre Corne personal account).
- Newsletter: process OUT until further notice (AL, 25/09/2026), nothing is sent; its set slot stays one send a week, Sunday 2:00 PM. Pinterest: 8 to 11 PM.
- Deletions (soft delete since 17/09/2026): when AL says delete, the row is deleted in Notion, and the next hourly sync marks every D1 line whose Notion page is archived, in the trash or gone from its base as status = deleted with a deleted_at stamp (migration 0058, previous status kept in status_before_delete). The rows stay in content_posts for history, /api/content-posts hides them unless ?include_deleted=1, so they leave the tracker and the week tables. A page restored from the Notion trash comes back on the next run.
History, oldest first. Older decisions, measurements and superseded values, kept verbatim, never deleted. Where a line below disagrees with the current state or the rules above, the current state and the rules win.
First version of this page (built 2026-09-12), superseded parts kept verbatim. Until 16/09/2026 the page showed five rolling weeks side by side in a horizontal scroller; AL wanted no horizontal scroll.
Until 18/09/2026: the week was shown in full on the page since 17/09/2026 (no more internal scroller: .scroller had max-height 78vh with overflow-y auto, then the JS fitHeight(), now a no-op); the page scrolls vertically, never horizontally; overscroll-behavior: none on the page and the table container removes the scroll bounce. Mobile layout unchanged (one block per code type).
20/09/2026, AL: every EO planner band is VIETNAM time (Asia/Ho_Chi_Minh, +07:00), generalised to every format on 21/09/2026. The hours printed on these pages do not change; what changes is the offset written on a row: a Posting Date is stamped +07:00, for example 2026-09-21T15:30:00+07:00. Pinterest stays in Eastern time, which is an audience constraint and not a preference. Dates already written are NOT moved (AL, 21/09/2026): every row keeps its absolute hour until AL says otherwise, because re-stamping them would move real publications. Only the 69 V16 shorts rows were re-stamped, by AL, on 20/09/2026. Any line below this one that still reads "Paris time" for a BAND is history and is superseded here.
Superseded on 22/09/2026 by AL: nothing stays on Paris time, Pinterest included. Every future row that was not already sent to PostFast was re-stamped that day, same wall clock, offset +07:00: 204 rows across 8 planners plus 78 Pinterest rows. The 13 pins already scheduled in PostFast keep their old instant, AL let that pass. The n8n workflows and this site now read Asia/Ho_Chi_Minh.
26/09/2026, AL: cadence halved; posts already scheduled kept as they are. (translated: "we must halve the number of EO posts per day, on every planner") The shared line of the Rules read until that day: "Cadences on every planner page set by AL 17/09/2026; every former "slot to set" band has a one hour window since 17/09/2026."